1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker 環境で C++ Pistache Webサービスを起動する

Last updated at Posted at 2023-08-18

Docker 環境で C++ Pistache Webサービスを起動する

こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu の Docker 環境で、C++ Pistache Web アプリケーションをコンテナとして起動する方法を紹介します。
pistache_on_docker.png

目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

実現すること

ローカル環境の WSL Ubuntu の Docker 環境で、Dockerfile からビルドした C++ Pistache Web サービスのカスタムコンテナイメージを起動します。

ネイティブイメージ形式のアプリをコンテナとして起動

実行環境

要素 概要
terminal ターミナル
Ubuntu OS
Docker コンテナ実行環境

Web サービス コンテナ

要素 概要
app-hello-pistache カスタムコンテナ
app ネイティブイメージ アプリケーション
pistache Web サーバー

技術トピック

Pistache とは?

こちらを展開してご覧いただけます。

Pistache (ピスターシュ)

Pistacheは、C++ で書かれた軽量な Web サーバーフレームワークです。

キーワード 内容
軽量 Pistache はコンパクトな設計であり、軽量なアプリケーションやマイクロサービスに適しています。
モダンな C++ C++11 以降のモダンな C++ スタンダードを活用しています。
RESTful APIサポート Pistache は RESTful API を構築するために設計されており、HTTP メソッド (GET、POST など) の処理を容易に行えます。
マルチスレッド マルチスレッドをサポートし、並行リクエストの処理が可能です。
イベント駆動 Pistache は非同期およびイベント駆動のアーキテクチャを採用しており、高いパフォーマンスを実現します。
シンプルな API 設計 Pistache のシンプルな API 設計により、Web サーバーの構築や API のエンドポイントの設定が簡単です。
パフォーマンス 軽量かつ高性能な設計により、効率的なリクエスト処理が可能です。
拡張性 ユーザー定義のミドルウェアやカスタムコンポーネントを統合することが容易です。
プラットフォーム非依存 Pistache はプラットフォーム非依存であり、さまざまな環境で利用できます。
アクティブなコミュニティ Pistache はアクティブなオープンソースコミュニティによってサポートされており、ドキュメントやサンプルコードが充実しています。

Dockerfile とは?

こちらを展開してご覧いただけます。

Dockerfile

Dockerfile は、Docker コンテナを構築するためのテキストファイルです。Docker コンテナはアプリケーションやサービスを実行するための環境を含む軽量でポータブルな仮想化ユニットです。

キーワード 内容
スクリプト形式 Dockerfile はシンプルなスクリプト形式で記述されるため、コンテナのビルドプロセスを自動化することが容易です。
レイヤー構造 Docker イメージは Dockerfile の各命令が実行される際にレイヤーとして生成され、再利用やキャッシュが可能な構造となっています。
バージョン管理 Dockerfile はテキストベースであるため、コードと同様にバージョン管理システムで管理しやすいです。
ポータビリティ Dockerfile により、アプリケーションとその依存関係が1つのコンテナイメージにパッケージ化されるため、異なる環境間での移植性が高まります。
自動化と効率化 Dockerfile を使用することで、アプリケーションのビルドや環境構築を自動化できます。これにより、手動での作業時間やヒューマンエラーが減り、開発・デプロイプロセスが効率的になります。
再現性 Dockerfile はビルド手順を完全に定義するため、異なる環境で同じアプリケーションを再現できます。これにより、開発、テスト、本番環境間での一貫性が確保されます。
環境の分離 Docker コンテナはホストシステムから分離されるため、アプリケーションの依存関係やライブラリの衝突を回避し、より安全な環境で実行できます。
拡張性 Dockerfile を使用することで、カスタムイメージを作成することができます。このため、特定のニーズに合わせてカスタマイズされたコンテナイメージを容易に作成できます。

開発環境

  • Windows 11 Home 22H2 を使用しています。

WSL の Ubuntu を操作していきますので macOS の方も参考にして頂けます。

WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます

> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47

Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04

Docker ※ こちらの関連記事からインストール方法をご確認いただけます

$ docker --version
Docker version 23.0.1, build a5ee5b1

この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。

作成する Web アプリケーションの仕様

No エンドポイント HTTPメソッド MIME タイプ
1 /api/data GET application/json

/api/data というエンドポイントに対して HTTP GET リクエストを送信すると、JSON データがレスポンスされるシンプルな Web サービスを実装します。
{"message":"Hello World!"}

Hello World を表示する手順

g++ (GNU Compiler Collection) のインストール

C++ コードをコンパイルするために、g++ をインストールします。

$ sudo apt update
$ sudo apt install g++

確認します。

$  g++ --version
g++ (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0

Pistache のインストール

Pistache をインストールします。

$ sudo add-apt-repository ppa:pistache+team/unstable
$ sudo apt update
$ sudo apt install libpistache-dev

プロジェクトの作成

プロジェクトフォルダを作成します。
※ ~/tmp/hello-pistache をプロジェクトフォルダとします。

$ mkdir -p ~/tmp/hello-pistache
$ cd ~/tmp/hello-pistache

アプリケーションファイルの作成

main.cpp ファイルを作成します。

$ vim main.cpp

ファイルの内容

main.cpp
#include <csignal>
#include <iostream>
#include <pistache/endpoint.h>
#include <pistache/http.h>
#include <pistache/http_headers.h>

using namespace Pistache;
using namespace Pistache::Http;
using namespace Pistache::Http::Header;
using namespace std;

class AppHandler : public Handler {

public:
    HTTP_PROTOTYPE(AppHandler)
    void onRequest(const Request& request, ResponseWriter response) override {
        // check the requested resource.
        if (request.resource() == "/api/data") {
            // set the content-type header.
            response.headers().add<ContentType>(MIME(Application, Json));
            // respond with a json message.
            response.send(Code::Ok, R"({"message":"Hello World!"})");
        } else {
            // respond with a not found error.
            response.send(Code::Not_Found);
        }
    }
};

int main() {
    // set receive port.
    Port port(9080);
    Address addr(Ipv4::any(), port);
    // start the server.
    cout << "Server is starting..." << endl;
    // register the shutdown handler.
    signal(SIGINT, [](int /* signal */) {
        cout << "Shutting down gracefully..." << endl;
        exit(0);
    });
    // listen and serve requests using the custom handler.
    listenAndServe<AppHandler>(addr);
    return 0;
}

アプリケーションのビルド

ソースコードをビルドします。

$ g++ -std=c++17 \
    -o app main.cpp \
    -lpistache -lpthread

ローカルで実行

ローカルで実行します。
停止するときは ctrl + C を押します。

$ ./app

別ターミナルから curl コマンドで確認します。

$ curl -v http://localhost:9080/api/data -w '\n'

出力

*   Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> GET /api/data HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: Close
< Content-Length: 26
<
* Closing connection 0
{"message":"Hello World!"}

ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。

コンテナイメージをビルド

Dockerfile を作成します。

$ vim Dockerfile

ファイルの内容

Dockerfile
# build the app.
FROM debian:12-slim as build-env

# set the working dir.
WORKDIR /app

# install build tools and libraries.
RUN apt-get update && \
    apt-get install -y build-essential cmake git libssl-dev g++ && \
    # install libpistache-dev.
    apt-get update && \
    apt-get install -y libpistache-dev

# copy main.cpp to the working dir.
COPY main.cpp /app/main.cpp

# build the app and optimize its size.
RUN g++ -std=c++17 -o app main.cpp -O2 -lpistache -lpthread && \
    strip app 

# set up the container.
FROM debian:12-slim

# set working dir.
WORKDIR /app

# copy the built app binary from the build-env.
COPY --from=build-env /app/app ./app

# install libpistache-dev and other tools.
RUN apt-get update && \
    apt-get install -y libpistache-dev && \
    # clean up package cache and temporary files.
    apt-get clean && rm -rf /var/lib/apt/lists/*

# expose the port.
EXPOSE 9080

# command to run the app.
CMD ["./app"]

Docker デーモンを起動します。

$ sudo service docker start
 * Starting Docker: docker    [ OK ]

Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。

コンテナイメージをビルドします。

$ docker build \
    --no-cache \
    --tag app-hello-pistache:latest .

コンテナイメージを確認します。

$ docker images | grep app-hello-pistache
app-hello-pistache   latest    c8f5df43c872   About a minute ago   98.4MB

ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナイメージをビルドすることができました。

コンテナを起動

ローカルでコンテナを起動します。
※ コンテナを停止するときは ctrl + C を押します。

$ docker run --rm \
    --publish 9080:9080 \
    --name app-local \
    app-hello-pistache:latest

ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナを起動することができました。

コンテナの動作確認

別ターミナルから curl コマンドで確認します。

$ curl -v http://localhost:9080/api/data -w '\n'

出力

*   Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> GET /api/data HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: Close
< Content-Length: 26
<
* Closing connection 0
{"message":"Hello World!"}

ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。

コンテナの状態を確認してみます。

$ docker ps
CONTAINER ID   IMAGE                       COMMAND   CREATED          STATUS          PORTS                                       NAMES
b85c71da88ab   app-hello-pistache:latest   "./app"   15 seconds ago   Up 14 seconds   0.0.0.0:9080->9080/tcp, :::9080->9080/tcp   app-local

コンテナに接続

別ターミナルからコンテナに接続します。

$ docker exec -it app-local /bin/sh

コンテナに接続後にディレクトリを確認します。
※ コンテナから出るときは ctrl + D を押します。

# pwd
/app
# ls -lah
total 32K
drwxr-xr-x 1 root root 4.0K Aug 10 09:53 .
drwxr-xr-x 1 root root 4.0K Aug 10 09:58 ..
-rwxr-xr-x 1 root root  23K Aug 10 09:53 app

top コマンドで状況を確認します。

# apt update
# apt install procps
# top
top - 10:00:11 up 10:09,  0 user,  load average: 0.00, 0.05, 0.05
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   7897.1 total,    172.0 free,   2680.4 used,   5340.2 buff/cache
MiB Swap:   2048.0 total,   1992.9 free,     55.1 used.   5216.7 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0   85516   3624   2964 S   0.0   0.0   0:00.02 app
   15 root      20   0    2576    904    816 S   0.0   0.0   0:00.01 sh
  205 root      20   0    8560   4636   2768 R   0.0   0.1   0:00.00 top

コンテナの情報を表示してみます。

# cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

このコンテナは Debian GNU/Linux をベースに作成されています。つまり、Debian GNU/Linux と同じように扱うことができます。

ディレクトリ・ファイル構成

プロジェクトのファイル構成を表示してみます。

$ tree
.
├── Dockerfile
├── app
└── main.cpp

まとめ

WSL Ubuntu の Docker 環境で、Dockerfile からビルドした C++ Pistache Web サービスのカスタムコンテナを起動することができました。

クラウド開発においては、Dockerfile の理解は重要です。自動ビルドツールもありますが、手動で書く必要があるケースもあります。Ubuntu を使うと Linux の知識も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。

どうでしたか? WSL Ubuntu で、C++ Pistache Web アプリケーションを手軽に実行することができます。ぜひお試しください。今後も C++ の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

推奨コンテンツ

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?