1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Azure Container Apps (ACA) に C 言語の CGI プログラム カスタムコンテナイメージをデプロイする

Last updated at Posted at 2023-09-14

Azure Container Apps (ACA) に C 言語の CGI プログラム カスタムコンテナイメージをデプロイする

こんにちは、@studio_meowtoon です。今回は、Azure Container Apps 環境で、C 言語の CGI プログラムをコンテナとして起動する方法を紹介します。
c-lang_on_azure-container-apps.png

目的

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

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

実現すること

Microsoft Azure Container Apps (ACA) に C 言語の CGI プログラム カスタムコンテナイメージをデプロイします。

この記事は学習目的であり、実際にはセキュリティリスクを伴う可能性があるため、実際のプロダクション環境では使用しないことを強くお勧めいたします。

CGI プログラムをコンテナとして起動

要素 概要
web-browser Web ブラウザ
Azure クラウド環境
Azure Container Apps コンテナ実行環境
app-hello-c-cgi カスタムコンテナ
app CGI プログラム
apache Web サーバー

この記事では、Docker Hub に公開するパブリックアクセス可能なカスタムコンテナイメージを使用しています。実際のシステム開発では、どのレジストリからコンテナイメージを取得するかは異なる場合がありますので、適宜ご確認ください。

技術背景

CGI とは?

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

CGI (シージーアイ) [Common Gateway Interface] は、ウェブサーバーと外部プログラムとの間でデータの受け渡しと相互作用を可能にする仕組みです。

キーワード 内容
動的なウェブページ生成 CGI を使用することで、動的なウェブページを生成し、ユーザーに対話的なコンテンツを提供できます。
プログラム言語の選択肢 C 言語は CGI プログラムを書くための一般的なプログラミング言語の1つであり、高性能で効率的なプログラムを開発できます。
ウェブサーバーとの連携 CGI プログラムは、ウェブサーバーからの HTTP リクエストを受け取り、クライアントに対するHTTPレスポンスを生成することができます。
外部データベースとの統合 C言語を使用した CGI プログラムは、外部データベースと連携してデータの取得や更新を行うことができます。
古典的なウェブ開発 CGI は古典的なウェブ開発のアプローチであり、現代のウェブアプリケーション開発では他の技術やアーキテクチャが一般的に使用されますが、歴史的な重要性があります。

CGI と C 言語の組み合わせは、ウェブサーバーとプログラムとの間でデータをやり取りし、動的なウェブコンテンツを生成するために使用される古典的なテクノロジーです。

Microsoft Azure Container Apps (ACA) とは?

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

Microsoft Azure Container Apps (ACA)

Azure 上で実行されるコンテナアプリケーションのプラットフォームです。

ACA は、Docker コンテナと Kubernetes クラスタの環境をサポートしており、開発者はコンテナイメージを作成して、Kubernetes リソースとしてデプロイすることができます。また、カスタムドメイン名をサポートしているため、自社のブランドを維持することができます。

メリット 説明
簡単なセットアップとデプロイ ACA は、簡単なユーザーインターフェイスを備えており、数回のクリックでコンテナアプリケーションをセットアップしてデプロイすることができます。
スケーラビリティ ACA は、自動的にスケーリングを行うことができます。アプリケーションに必要なリソースが増加した場合、ACA は自動的に必要なリソースを追加して処理を分散します。
セキュリティ ACA は、コンテナアプリケーションを実行する際に必要なセキュリティ機能を提供しています。例えば Azure Active Directory との統合や、コンテナレベルでのアクセス制御などがあります。
コスト効率 ACA は、必要なときに必要なリソースを追加するため、無駄なリソースの使用を最小限に抑えることができます。また、必要なリソースに対してのみ支払いを行うため、コスト効率的に利用することができます。

開発環境

  • 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

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

$ az --version
azure-cli                         2.45.0
core                              2.45.0
telemetry                          1.0.8

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

作成する Web サイトの仕様

Web ブラウザに Hello World! と表示します。

"Hello World" を表示する手順

プロジェクトフォルダを作成

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

$ mkdir -p ~/tmp/hello-c-cgi
$ cd ~/tmp/hello-c-cgi

C コンパイラのインストール

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

$ sudo apt update
$ sudo apt install gcc

確認します。

$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

C プログラムの作成

hello_world.c を作成します。

$ vim hello_world.c

ファイルの内容

hello_world.c
#include <stdio.h>

int main() {
    printf("Content-Type: text/html\n\n");
    printf("<html><head><title>Hello CGI</title></head><body>");
    printf("<h1>Hello World!</h1>");
    printf("</body></html>");
    return 0;
}

ビルド(コンパイル)します。

$ gcc -o app hello_world.c -O2
説明を開きます。
要素 説明
gcc GCC (GNU Compiler Collection) の C コンパイラを呼び出すコマンドです。C 言語のソースコードをコンパイルして実行可能なプログラムに変換します。
-o app -o オプションは、コンパイルされた実行可能ファイルの名前を指定するためのオプションです。ここでは、出力ファイルの名前を "app" に指定しています。
hello_world.c コンパイル対象の C 言語ソースコードファイルの名前です。このコマンドでは、"hello_world.c" というファイルをコンパイルします。
-O2 -O2 オプションは、コンパイラに最適化のレベルを指示します。具体的には、プログラムの実行速度を向上させるための最適化を有効にします。-O2 は、一般的な最適化レベルの一つで、プログラムの実行速度を向上させつつも、コンパイルにはある程度の時間がかかります。コードを最適化することで、プログラムの効率性が向上し、実行速度が向上することがあります。

実行します。

$ ./app

出力

Content-Type: text/html

<html><head><title>Hello CGI</title></head><body><h1>Hello World!</h1></body></html>

ここまでの手順で、C 言語による最小限の CGI プログラムの実行ファイルを作成することができました。

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

Dockerfile を作成します。

$ vim Dockerfile

ファイルの内容

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

# install httpd.
RUN apt update \
    && apt install -y apache2 \
    && rm -rf /var/lib/apt/lists/* \
    && apt clean

# enable the cgi module in httpd.
RUN a2enmod cgi

# creates a directory for the cgi.
RUN mkdir -p /usr/lib/cgi-bin

# copies the local app to the container.
COPY app /usr/lib/cgi-bin/app

# sets permissions for the cgi.
RUN chmod +x /usr/lib/cgi-bin/app

# sets a script alias directive in httpd config file.
RUN sed -i '/ScriptAlias \/cgi-bin\/ \/usr\/lib\/cgi-bin\//d' /etc/apache2/conf-available/serve-cgi-bin.conf && \
    echo "ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/" >> /etc/apache2/conf-available/serve-cgi-bin.conf && \
    a2enconf serve-cgi-bin

# sets the server name directive in httpd config file.
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf

# expose the port.
EXPOSE 80

# command to run httpd.
CMD ["apachectl","-D","FOREGROUND"]
説明を開きます。
要素 説明
FROM debian:12-slim ベースイメージとして Debian 12 のスリムバージョンを使用します。
RUN apt update パッケージマネージャのパッケージリストを更新します。
RUN apt install -y apache2 Apache HTTP Server (httpd) をインストールします。-y オプションはインストールプロセス中の確認プロンプトを自動的に "Yes" と回答することを示します。
RUN rm -rf /var/lib/apt/lists/* インストール後、不要なパッケージリストキャッシュを削除します。これにより、Docker イメージサイズを最小限に抑えます。
RUN apt clean インストール時に生成された一時ファイルやキャッシュをクリーンアップします。
RUN a2enmod cgi Apache HTTP Server で CGI モジュールを有効化します。これにより、Apache は CGI プログラムを実行できるようになります。
RUN mkdir -p /usr/lib/cgi-bin CGI アプリケーション用のディレクトリ /usr/lib/cgi-bin を作成します。
COPY app /usr/lib/cgi-bin/app ローカルの app ファイル (CGI アプリケーションの実行可能ファイル) をコンテナ内の /usr/lib/cgi-bin/ ディレクトリにコピーします。
RUN chmod +x /usr/lib/cgi-bin/app CGI アプリケーションファイルに実行権限を付与します。これにより、コンテナ内で実行できます。
RUN sed -i '/ScriptAlias /cgi-bin/ /usr/lib/cgi-bin//d' /etc/apache2/conf-available/serve-cgi-bin.conf && \ echo "ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/" >> /etc/apache2/conf-available/serve-cgi-bin.conf && \ a2enconf serve-cgi-bin Apache の設定ファイル serve-cgi-bin.conf を編集して、CGI スクリプトのエイリアスディレクトリを設定します。
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf Apache の設定ファイルに ServerName ディレクティブを追加して、サーバーのホスト名を設定します。
EXPOSE 80 コンテナがポート 80 を外部に公開することを宣言します。これにより、ホストマシンからコンテナの Apache HTTP Server にアクセスできます。
CMD ["apachectl","-D","FOREGROUND"] コンテナが起動された際に実行されるコマンドを指定します。ここでは Apache HTTP Server をバックグラウンドで実行します。

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

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

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

$ docker build \
    --no-cache \
    -t app-hello-c-cgi .

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

$ docker images | grep app-hello-c-cgi
app-hello-c-cgi    latest    46bed0912d2c    9 seconds ago    187MB

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

コンテナを起動

ローカルでコンテナを起動します。

$ docker run --rm \
    --name app-local \
    -p 8080:80 \
    app-hello-c-cgi:latest

このコンテナを停止するには、以下のコマンドを実行します。

$ docker stop app-local

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

コンテナの動作確認

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

$ curl -v http://localhost:8080/cgi-bin/app -w '\n'

出力

*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /cgi-bin/app HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 18 Aug 2023 06:22:40 GMT
< Server: Apache/2.4.57 (Debian)
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html
<
* Connection #0 to host localhost left intact
<html><head><title>Hello CGI</title></head><body><h1>Hello World!</h1></body></html>

Web ブラウザで以下の URL にアクセスして確認します。

http://localhost:8080/cgi-bin/app

image.png

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

Docker Hub にコンテナイメージを登録

Docker Hub にログインします。

$ docker login
Login Succeeded

コンテナイメージにタグを付けます。

ここで $USER という埋め込み変数は、Ubuntu のシェル変数 USER のことです。つまり、カスタムコンテナイメージを Docker Hub にプッシュする際に指定するアカウント名と、Ubuntuユーザー名を同じにすると、イメージの取り扱いが簡単になります。ただし、この方法は検証用途に限定されます。

$ docker tag app-hello-c-cgi:latest \
    $USER/app-hello-c-cgi:latest

Docker Hub にコンテナイメージをプュシュします。

$ docker push $USER/app-hello-c-cgi:latest

ここまでの手順で、Docker Hub$USER/app-hello-c-cgi:latest というカスタムコンテナイメージをプッシュすることができました。

シェル変数の作成

シェル変数として、Ubuntu に以下の値を作成します。状況により、コンテナ アプリの名前を変える必要があります。

location_name=japaneast
resource_group_name=rg-hello
containerapp_env_name=cae-hello
containerapp_name=ca-hello-c-cgi
container_image_name=app-hello-c-cgi:latest

Azure 環境にサインイン

こちらの関連記事の続きから手順を説明する記事となります。

Azure CLI でログインします。

$ az login

Azure 環境

リソースグループ

リソースグループを作成します。

Microsoft.Resources/resourceGroups
$ az group create \
    --name $resource_group_name \
    --location $location_name

コンテナ アプリ環境

コンテナ アプリ環境を作成します。
※ Kubernetes 基盤の環境がベースとなっているので少し時間がかかります。

Microsoft.App/managedEnvironments
$ az containerapp env create \
    --resource-group $resource_group_name \
    --name $containerapp_env_name \
    --location $location_name

コンテナ アプリ

コンテナ アプリの作成とデプロイを行います。

Microsoft.App/containerApps
$ az containerapp create \
    --resource-group $resource_group_name \
    --environment $containerapp_env_name \
    --name $containerapp_name \
    --image $USER/$container_image_name \
    --target-port 80 \
    --ingress 'external' \
    --min-replicas 0

--min-replicas 0: と設定することにより、アクセスが300秒間ない場合にアプリケーションがスケールゼロ状態に移行します。

コンテナ アプリを削除する場合は以下のコマンドを実行します。

$ az containerapp delete \
    --resource-group $resource_group_name \
    --name $containerapp_name

コンテナ アプリの FQDN をシェル変数 containerapp_fqdn として取得します。

$ containerapp_fqdn=$(az containerapp show \
    --resource-group $resource_group_name \
    --name $containerapp_name \
    --query 'properties.configuration.ingress.fqdn' \
    --output tsv)

コンテナ アプリの FQDN を確認します。

$ set | grep containerapp_fqdn
containerapp_fqdn=ca-hello-c-cgi.whitewave-41bebcec.japaneast.awesomecontainerapps.io

Azure Portal の確認

image.png
image.png

ここまでの作業で、Azure Container Appsコンテナ アプリをデプロイすることができました。

コンテナの動作確認

ターミナルから Web ブラウザを開き、確認します。

$ wslview https://$containerapp_fqdn/cgi-bin/app

image.png

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

コンテナに接続

コンテナ アプリに接続

$ az containerapp exec \
    --resource-group $resource_group_name \
    --name $containerapp_name

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

# pwd
/
# cd /usr/lib/cgi-bin
# ls -lah
total 24K
drwxr-xr-x 1 root root 4.0K Sep 14 06:56 .
drwxr-xr-x 1 root root 4.0K Sep 14 06:56 ..
-rwxr-xr-x 1 root root  16K Sep 14 06:44 app

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

# apt update
# apt install procps
# top
top - 07:38:33 up  1:09,  0 user,  load average: 0.21, 0.19, 0.18
Tasks:   7 total,   1 running,   6 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.8 us,  1.3 sy,  0.0 ni, 94.8 id,  0.0 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :  15990.8 total,   7951.0 free,   2363.9 used,   6029.1 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  13626.9 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 root      20   0    2576    892    800 S   0.0   0.0   0:00.02 apachectl
      9 root      20   0    6624   5360   4016 S   0.0   0.0   0:00.01 apache2
     10 www-data  20   0    6284   2900   1560 S   0.0   0.0   0:00.00 apache2
     11 www-data  20   0 1932356  11472   3412 S   0.0   0.1   0:00.01 apache2
     12 www-data  20   0 1932332  13288   3268 S   0.0   0.1   0:00.01 apache2
     69 root      20   0    2576    936    844 S   0.0   0.0   0:00.01 sh
    176 root      20   0    8596   4668   2796 R   0.0   0.0   0:00.00 top

top コマンドで cpu を表示した状況です。

top - 07:38:55 up  1:09,  0 user,  load average: 0.22, 0.19, 0.18
Tasks:   7 total,   1 running,   6 sleeping,   0 stopped,   0 zombie
%Cpu0  :  4.7 us,  2.0 sy,  0.0 ni, 93.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  3.4 us,  1.7 sy,  0.0 ni, 95.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  2.7 us,  2.0 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  4.4 us,  1.3 sy,  0.0 ni, 94.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15990.8 total,   7963.4 free,   2350.1 used,   6030.5 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  13640.7 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 root      20   0    2576    892    800 S   0.0   0.0   0:00.02 apachectl
      9 root      20   0    6624   5360   4016 S   0.0   0.0   0:00.01 apache2
     10 www-data  20   0    6284   2900   1560 S   0.0   0.0   0:00.00 apache2
     11 www-data  20   0 1932356  11472   3412 S   0.0   0.1   0:00.01 apache2
     12 www-data  20   0 1932332  13288   3268 S   0.0   0.1   0:00.01 apache2
     69 root      20   0    2576    936    844 S   0.0   0.0   0:00.01 sh
    176 root      20   0    8596   4668   2796 R   0.0   0.0   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 と同じように扱うことができます。

パフォーマンスの計測

コンテナ 環境

項目 バージョン
Base Image Debian GNU/Linux 12

コンテナ リソースの割り当て

項目 設定値
CPU コアの数 0.5
メモリ サイズ(Gi) 1Gi

メトリック:CPU使用率

状況 CPU使用率
集計:平均 0.15mコア

メトリック:メモリ使用量

状況 メモリ使用量
集計:平均 17.8MB

まとめ

Azure Container Apps 環境で、Dockerfile からビルドした C 言語の CGI プログラムのカスタムコンテナイメージを起動することができました。

GCCDockerAzure CLI を使って、C 言語の CGI プログラムの開発からコンテナイメージの作成、Azure 環境へのデプロイまで、すべてをターミナルから行うことができます。このように、クラウドでのシステム開発に必要なスキルや理解を深めることができます。初めての人でも簡単に手順を追うことができるので、ぜひ挑戦してみてください。

どうでしたか? 検証目的として、Azure Container Apps 環境で、C 言語の CGI プログラムをコンテナとして手軽に起動することができます。ぜひお試しください。今後も Azure の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

推奨コンテンツ

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?