Docker 環境で C++ Pistache Webサービスを起動する
こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu の Docker 環境で、C++ Pistache Web アプリケーションをコンテナとして起動する方法を紹介します。
目的
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
ファイルの内容
#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
ファイルの内容
# 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++ の開発環境などを紹介していきますので、ぜひお楽しみにしてください。
推奨コンテンツ