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

Amazon ECS入門 - Nginxをデプロイして学ぶコンテナ運用の基本

0
Last updated at Posted at 2026-06-30

はじめに

Docker Composeを使うと、ローカル環境で簡単にコンテナを起動・管理できます。

一方、本番環境では、以下のような要件が出てきます。

  • コンテナ障害時に自動復旧したい
  • 複数のコンテナへ負荷分散したい
  • コンテナ数を簡単に増やしたい
  • CloudWatch Logsでログを確認したい
  • AWS IAMで権限制御したい

このような用途で利用されるのが、Amazon ECSです。

本記事では、Amazon ECS Managed Instancesを使ってNginxを構築します。

また、HTMLファイルはDockerイメージに含めず、Amazon S3に保存した index.htmlS3 Files でコンテナへマウントします。

これにより、S3上のHTMLを書き換えるだけで、Nginxの表示内容へ反映される構成を作ります。

ECSとは

Amazon ECSは、AWSが提供するコンテナオーケストレーションサービスです。

Docker Composeが主に1台のサーバー上でコンテナを起動する仕組みであるのに対し、ECSはAWS上で複数のコンテナを管理できます。

Docker Compose

Server
└── nginx
Amazon ECS

ECS Cluster
└── ECS Service
    └── ECS Task
        └── nginx

ECSでは、コンテナを直接起動するのではなく、以下のような構成で管理します。

ECSの要素 説明
Cluster コンテナを実行する基盤
Task Definition コンテナの設計図
Task Task Definitionから起動される実行単位。1つ以上のコンテナを含められる
Service Task数を維持する仕組み
Capacity Provider コンテナ実行基盤の管理

今回作成する構成

今回は以下の構成を作成します。

既存VPC

├── Private Subnet-A
│   ├── 踏み台サーバー
│   ├── Internal ALB
│   ├── S3 Files Mount Target
│   └── ECS Managed Instance
│       └── nginx Task
│
├── Private Subnet-C
│   ├── Internal ALB
│   ├── S3 Files Mount Target
│   └── ECS Managed Instance
│       └── nginx Task
│
└── Amazon S3
    └── index.html
        ↑
        S3 Filesでマウント

ポイントは以下です。

項目 内容
ECS実行基盤 Managed Instances
OS Amazon Linux
VPC 既存VPC
Subnet Private Subnet
ALB Internal ALB
Target Group IPターゲット
Webサーバー nginx:latest
HTML配置先 Amazon S3
HTMLマウント先 /usr/share/nginx/html
S3 Files接続 S3 Filesファイルシステムとmount targetを利用
動作確認 踏み台サーバーからInternal ALBへアクセス
スケール確認 Desired Countを1から2へ変更

S3バケット名について

S3バケット名はグローバルで一意である必要があります。

そのため、AWSアカウントIDを含めた名前にします。

ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an

例です。

ecs-nginx-demo-123456789012-ap-northeast-1-an

このようにすることで、他のAWSアカウントとバケット名が重複しにくくなります。

S3バケットを作成する

AWSマネジメントコンソールで以下を開きます。

S3 > 汎用バケット > バケットを作成

設定値は以下です。

項目 設定値
バケットタイプ 汎用
バケット名 ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an
AWSリージョン アジアパシフィック(東京)ap-northeast-1
オブジェクト所有者 ACL無効
パブリックアクセスをすべてブロック 有効
バケットのバージョニング 無効
デフォルト暗号化 Amazon S3 マネージドキー
バケットキー 有効

image.png

作成後、バケットを開きます。

index.htmlをアップロードする

ローカルPCで以下のファイルを作成します。

ファイル名は index.html です。

<!DOCTYPE html>
<html>
<head>
  <title>ECS S3 Files Demo</title>
</head>
<body>
  <h1>Hello ECS</h1>
</body>
</html>

S3バケットを開き、以下の順に操作します。

S3 > 対象バケット > オブジェクト > アップロード

設定値は以下です。

項目 設定値
アップロードファイル index.html
保存先 バケット直下
アクセス許可 変更なし
ストレージクラス 標準

アップロード後、以下のようになっていれば問題ありません。

s3://ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/index.html

S3 Filesファイルシステムを作成する

S3 FilesをECS Taskへマウントするには、S3バケットだけでは不十分です。

事前に以下が必要です。

項目 内容
S3バケット HTMLファイルを保存する場所
S3 Filesファイルシステム ECSからマウントするファイルシステム
Mount target VPC内からS3 Filesへ接続するためのネットワークエンドポイント
Task IAM Role ECS TaskがS3 FilesとS3を読むためのIAMロール
Security Group ECS Taskからmount targetのTCP 2049へ到達できる設定

AWSマネジメントコンソールで以下を開きます。

S3 > S3 Files > ファイルシステムを作成

設定値は以下です。

項目 設定値
ファイルシステム名 fs-ecs-nginx-html
関連付けるS3バケット ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an
VPC ECS Taskを起動する既存VPC
Mount target Private Subnet-A、Private Subnet-C
Security Group 後述の sg-s3files-mount-target

作成後、S3 FilesファイルシステムIDを控えます。

fs-XXXXXXXXXXXXXXXXX

Access Pointを利用する場合は、Access Point ARNも控えます。

arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/fs-XXXXXXXXXXXXXXXXX/access-point/fsap-XXXXXXXXXXXXXXXXX

IAMポリシーを作成する

S3 FilesをECS Taskへマウントするには、S3オブジェクト読み取り権限に加えて、S3 Filesファイルシステムへの接続権限が必要です。

AWSマネジメントコンソールで以下を開きます。

IAM > ポリシー > ポリシーの作成

「JSON」を選択し、以下を入力します。

<AWSアカウントID><S3 FilesファイルシステムID>、必要に応じて <S3 Files Access Point ID> を置き換えます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3FilesMount",
      "Effect": "Allow",
      "Action": [
        "s3files:ClientMount",
        "s3files:ClientRootAccess"
      ],
      "Resource": [
        "arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/<S3 FilesファイルシステムID>",
        "arn:aws:s3files:ap-northeast-1:<AWSアカウントID>:file-system/<S3 FilesファイルシステムID>/access-point/<S3 Files Access Point ID>"
      ]
    },
    {
      "Sid": "AllowListBucket",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an"
    },
    {
      "Sid": "AllowReadObjects",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": "arn:aws:s3:::ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/*"
    }
  ]
}

Access Pointを使わない場合は、Access Point ARNの行は削除します。

ポリシー名は以下にします。

S3FilesReadOnlyForEcsNginx

設定値です。

項目 設定値
ポリシー名 S3FilesReadOnlyForEcsNginx
説明 Allow ECS task to read nginx html files from S3 Files

IAMロールを作成する

次に、ECS TaskからS3 FilesとS3を読むためのIAMロールを作成します。

AWSマネジメントコンソールで以下を開きます。

IAM > ロール > ロールを作成

設定値は以下です。

項目 設定値
信頼されたエンティティタイプ AWSサービス
ユースケース Elastic Container Service
ユースケース詳細 Elastic Container Service Task

許可ポリシーで、先ほど作成した以下のポリシーを選択します。

S3FilesReadOnlyForEcsNginx

ロール名は以下にします。

ecs-task-role-nginx-s3files
項目 設定値
ロール名 ecs-task-role-nginx-s3files
説明 Task role for nginx to mount S3 Files

このロールは、後ほどTask Definitionの Task role に指定します。

Security Groupを作成する

今回必要なSecurity Groupは3つです。

Security Group名 用途
sg-ecs-nginx-alb Internal ALB用
sg-ecs-nginx-task ECS Task用
sg-s3files-mount-target S3 Files mount target用

通信経路は以下です。

踏み台サーバー
    ↓ HTTP:80
Internal ALB
    ↓ HTTP:80
ECS Task nginx
    ↓ TCP:2049
S3 Files Mount Target

ALB用Security Groupを作成する

AWSマネジメントコンソールで以下を開きます。

EC2 > セキュリティグループ > セキュリティグループを作成

基本情報です。

項目 設定値
セキュリティグループ名 sg-ecs-nginx-alb
説明 Security group for internal ALB of ECS nginx
VPC 既存VPC

インバウンドルールです。

タイプ プロトコル ポート ソース
HTTP TCP 80 踏み台サーバーのSecurity Group

踏み台サーバーのSecurity Groupをソースに指定します。

例です。

sg-bastion

アウトバウンドルールです。

タイプ プロトコル ポート 宛先
すべてのトラフィック すべて すべて 0.0.0.0/0

ALBからECS Taskへ通信するため、アウトバウンドはデフォルトのままで問題ありません。

ECS Task用Security Groupを作成する

同じく以下を開きます。

EC2 > セキュリティグループ > セキュリティグループを作成

基本情報です。

項目 設定値
セキュリティグループ名 sg-ecs-nginx-task
説明 Security group for ECS nginx tasks
VPC 既存VPC

インバウンドルールです。

タイプ プロトコル ポート ソース
HTTP TCP 80 sg-ecs-nginx-alb

ここでは、踏み台サーバーからの直接アクセスは許可しません。

ECS TaskにはALBからのみアクセスさせます。

アウトバウンドルールです。

タイプ プロトコル ポート 宛先
NFS TCP 2049 sg-s3files-mount-target
HTTPS TCP 443 S3またはインターネット向け

検証用途でアウトバウンドを 0.0.0.0/0 の全許可にしている場合、上記の通信は含まれます。

S3 Files Mount Target用Security Groupを作成する

S3 Filesはmount targetへNFS相当の通信を行います。

そのため、ECS Task側からmount targetのTCP 2049へ到達できる必要があります。

EC2 > セキュリティグループ > セキュリティグループを作成

基本情報です。

項目 設定値
セキュリティグループ名 sg-s3files-mount-target
説明 Security group for S3 Files mount target
VPC 既存VPC

インバウンドルールです。

タイプ プロトコル ポート ソース
NFS TCP 2049 sg-ecs-nginx-task

アウトバウンドルールはデフォルトのままで問題ありません。

Private Subnet利用時の注意点

今回の構成ではECS TaskをPrivate Subnetに配置し、Public IPを無効にします。

そのため、ECS TaskやManaged Instanceが外部サービスへ到達する経路が必要です。

特に、この記事ではDocker Hubの公式イメージを利用します。

nginx:latest

Docker Hubからイメージを取得するには、Private Subnetからインターネットへ出る経路が必要です。

用途 必要な経路
Docker Hubから nginx:latest をpull NAT GatewayまたはNAT Instance
S3 APIへアクセス NAT Gateway、NAT Instance、またはS3 Gateway Endpoint
S3 Files mount targetへ接続 同一VPC内のmount targetとTCP 2049のSecurity Group許可

S3 Gateway EndpointだけではDocker Hubへは到達できません。

閉域寄りの構成にしたい場合は、nginxイメージをECRへ置き、ECR用VPC EndpointとS3 Gateway Endpointを利用する構成にします。

Target Groupを作成する

ALBからECS Taskへ転送するため、Target Groupを作成します。

AWSマネジメントコンソールで以下を開きます。

EC2 > ターゲットグループ > ターゲットグループの作成

基本設定

項目 設定値
ターゲットタイプ IPアドレス
ターゲットグループ名 tg-ecs-nginx
プロトコル HTTP
ポート 80
IPアドレスタイプ IPv4
VPC 既存VPC
プロトコルバージョン HTTP1

今回はECS Serviceと連携するため、ターゲットタイプは IPアドレス にします。

ECS Taskは awsvpc ネットワークモードでENIを持つため、ALBはTaskのIPアドレスへ直接転送します。

ヘルスチェック設定

項目 設定値
ヘルスチェックプロトコル HTTP
ヘルスチェックパス /
正常しきい値 5
非正常しきい値 2
タイムアウト 5秒
間隔 30秒
成功コード 200

Nginxは / にアクセスすると index.html を返します。

そのため、ヘルスチェックパスは / で問題ありません。

ターゲット登録

作成時点ではターゲットを手動登録しません。

ECS Serviceを作成すると、ECSが自動でTaskのIPアドレスをTarget Groupへ登録します。

そのため、ターゲット登録画面では何も選択せずに作成します。

Internal ALBを作成する

AWSマネジメントコンソールで以下を開きます。

EC2 > ロードバランサー > ロードバランサーの作成

「Application Load Balancer」を選択します。

基本設定

項目 設定値
ロードバランサー名 alb-ecs-nginx-internal
スキーム 内部
IPアドレスタイプ IPv4

スキームは 内部 を選択します。

これにより、ALBはPrivate Subnet内でのみ利用されます。

ネットワークマッピング

項目 設定値
VPC 既存VPC
サブネット Private Subnet-A、Private Subnet-C

ALBは高可用性のため、2つ以上のAZに配置します。

今回はPrivate Subnetを2つ選択します。

Security Group

項目 設定値
Security Group sg-ecs-nginx-alb

Listener

項目 設定値
プロトコル HTTP
ポート 80
デフォルトアクション tg-ecs-nginx へ転送

作成後、ALBのDNS名を控えます。

例です。

internal-alb-ecs-nginx-internal-xxxxxxxx.ap-northeast-1.elb.amazonaws.com

ECSクラスターを作成する

AWSマネジメントコンソールで以下を開きます。

ECS > Clusters > Create Cluster

Managed Instancesを指定する場合、クラスター作成時にECSがManaged Instances用のCapacity Providerを作成します。

このとき、ECSがEC2インスタンスを起動・管理するための設定も必要です。

主に確認する項目は以下です。

項目 内容
Subnets ECS Managed Instancesを起動するサブネット
Security group ECS Managed Instancesに付与するSecurity Group
Instance profile Managed Instancesとして起動されるEC2インスタンスに付与するIAM instance profile
Infrastructure role ECSがManaged Instances基盤をユーザーの代わりに管理するためのIAM role

設定値は以下です。

項目 設定値
Cluster name ecs-cluster-nginx
Infrastructure Managed Instances
OS Amazon Linux
VPC 既存VPC
Subnets Private Subnet-A、Private Subnet-C
Security group ECS Managed Instances用Security Group
Instance profile 新しいインスタンスロールを作成する
Infrastructure role 新しいインフラストラクチャロールを作成する

Subnets

ここで指定するSubnetsは、ECS Managed Instances、つまりECSが管理するEC2インスタンスを起動するサブネットです。

今回の構成ではPrivate Subnet-AとPrivate Subnet-Cを指定します。

Private Subnet-A
Private Subnet-C

複数AZのPrivate Subnetを指定することで、ECS Managed Instancesを複数AZへ分散できます。

すべてのサブネットは同じVPCに属している必要があります。

また、Private SubnetでDocker Hubの nginx:latest を利用する場合、Managed InstancesがDocker Hubへ到達できる必要があります。

そのため、以下のどちらかを用意します。

方法 内容
NAT GatewayまたはNAT Instance Docker Hubから直接pullする場合
ECR + VPC Endpoint nginxイメージをECRに置き、閉域寄りにする場合

S3 Gateway EndpointだけではDocker Hubへは到達できません。

Instance profile

Instance profileは、ECS Managed Instancesとして起動されるEC2インスタンスに付与されるIAM instance profileです。

このinstance profileは、ECS container agentやDocker daemonがECSと通信し、タスクを実行するために使われます。

AWS管理ポリシーのInfrastructure roleを使う場合、instance profile名は ecsInstanceRole で始まる名前にします。

例です。

ecsInstanceRole

既存のinstance profileを使う場合は、ECS Managed Instancesがクラスターへ登録され、タスクを実行できる権限を持っている必要があります。

Infrastructure role

Infrastructure roleは、ECSがユーザーの代わりにManaged Instances基盤を管理するためのIAM roleです。

このroleにより、ECSはManaged Instancesの起動、終了、管理などに必要なAWS APIを呼び出します。

AWS管理ポリシーを使う場合は、以下を付与したroleを指定します。

AmazonECSInfrastructureRolePolicyForManagedInstances

このroleはTask roleやTask execution roleとは別物です。

Role 用途
Infrastructure role ECSがManaged Instances基盤を管理する
Instance profile Managed Instancesとして起動されるEC2インスタンスに付与される
Task role コンテナ内アプリケーションがAWS APIを呼ぶ
Task execution role ECSがイメージ取得やCloudWatch Logs出力を行う

今回の記事では、Capacity Providerを個別に事前作成せず、クラスター作成時にECSへ自動作成させます。

ただし、Managed Instancesを選ぶ場合は、Subnets、Instance profile、Infrastructure roleが正しく指定されていることを確認します。

Task Definitionを作成する

AWSマネジメントコンソールで以下を開きます。

ECS > Task definitions > Create

Task Definition基本設定

項目 設定値
Task definition family nginx-task
Launch type Managed Instances
Network mode awsvpc
Task role ecs-task-role-nginx-s3files
Task execution role ecsTaskExecutionRole

Task roleには、S3 FilesでS3を読むためのロールを指定します。

Task execution roleは、ECSがコンテナイメージ取得やCloudWatch Logs出力に使うロールです。

通常は ecsTaskExecutionRole を利用します。

Task size

項目 設定値
CPU 1 vCPU
Memory 3 GB

Nginxの簡単な検証なので、デフォルト値で十分です。

コンテナを追加する

Task Definition作成画面で、コンテナを追加します。

コンテナ基本設定

項目 設定値
Container name nginx
Image URI nginx:latest
Essential container Yes
Private registry authentication Off

Image URIについて

今回はDocker Hubで公開されている公式Nginxイメージを利用します。

nginx:latest

これは、Docker Hub上のNginx公式イメージの最新版タグを意味します。

ECRを使う場合は以下のようなURIになります。

123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/nginx:latest

今回はECRは使わず、Docker Hubの nginx:latest を直接指定します。

Private SubnetでDocker Hubを利用するため、NAT GatewayまたはNAT Instanceが必要です。

Port mappings

項目 設定値
Container port 80
Protocol TCP
Port name nginx-80-tcp
App protocol HTTP

Nginxはコンテナ内で80番ポートをListenします。

ALBからもHTTP:80でアクセスするため、Container portは80にします。

CloudWatch Logsを設定する

コンテナのログ設定を行います。(デフォルト値)

項目 設定値
Log collection 有効
Log driver awslogs
Log group /ecs/nginx-task
Region ap-northeast-1
Stream prefix ecs

NginxのアクセスログやエラーログをCloudWatch Logsで確認できるようになります。

S3 Files Volumeを設定する

Task DefinitionのVolume設定で、S3 Filesを追加します。

Volume設定

項目 設定値
Volume name s3-html-volume
Volume type S3 Files
File System fs-XXXXXXXXXXXXXXXXX
Access Point 必要に応じて作成済みAccess Point
S3 prefix /

File Systemには、先ほど作成したS3 Filesファイルシステムを指定します。

S3 prefixはバケット直下を利用するため / にします。

つまり、以下のファイルがコンテナ内に見えるようになります。

s3://ecs-nginx-demo-<AWSアカウントID>-ap-northeast-1-an/index.html

↓

/usr/share/nginx/html/index.html

Mount points

コンテナ nginx に対して、以下のマウント設定を追加します。

項目 設定値
Container nginx
Source volume s3-html-volume
Container path /usr/share/nginx/html
Read only 有効

Nginx公式イメージでは、HTMLの公開ディレクトリは以下です。

/usr/share/nginx/html

ここへS3 Filesをマウントすることで、S3上の index.html がNginxのトップページになります。

ここまででTask Definitionの設定は完了です。

ECS Serviceを作成する

AWSマネジメントコンソールで以下を開きます。

ECS > Clusters > ecs-cluster-nginx > Services > Create

Service基本設定

項目 設定値
Compute options Capacity provider strategy
Capacity provider Managed Instances作成時に自動作成されたもの
Task definition Family nginx-task
Service name nginx-service
Desired tasks 1

Networking

項目 設定値
VPC 既存VPC
Subnets Private Subnet-A、Private Subnet-C
Security group sg-ecs-nginx-task
Public IP Disabled

今回はPrivate Subnet構成のため、Public IPは無効にします。

Load balancing

すべて先ほど作成したロードバランサーとターゲットグループを選択します。

項目 設定値
Load balancer type Application Load Balancer
Load balancer alb-ecs-nginx-internal
Listener HTTP:80
Target group tg-ecs-nginx
Container nginx
Container port 80

ECS Serviceを作成すると、Taskが起動し、TaskのIPアドレスがTarget Groupへ自動登録されます。

動作確認する

ECS Service作成後、以下を確認します。

ECS > Clusters > ecs-cluster-nginx > Services > nginx-service

Tasksタブで、Taskの状態が以下になっていることを確認します。

RUNNING

次にTarget Groupを確認します。

EC2 > ターゲットグループ > tg-ecs-nginx > Targets

TaskのIPアドレスが登録され、状態が以下になっていれば正常です。

healthy

踏み台サーバーからALBへアクセスします。

curl http://<Internal ALBのDNS名>

以下のように表示されれば成功です。

<h1>Hello ECS</h1>

S3のHTMLを書き換えて反映確認する

S3の index.html を更新します。

<!DOCTYPE html>
<html>
<head>
  <title>ECS S3 Files Demo</title>
</head>
<body>
  <h1>Hello ECS Version2</h1>
</body>
</html>

アップロード後、少し待ってから踏み台サーバーで再度確認します。

curl http://<Internal ALBのDNS名>

以下のように変われば成功です。

<h1>Hello ECS Version2</h1>

Dockerイメージの再作成も、ECS Serviceの更新も不要です。

タスク数を増やす

ECS Serviceを更新し、Task数を増やします。

ECS > Clusters > ecs-cluster-nginx > Services > nginx-service > Update

Desired tasksを変更します。

項目 変更前 変更後
Desired tasks 1 2

更新後、TasksタブでTaskが2つ起動していることを確認します。

RUNNING Task: 2

Target Groupでも、登録済みターゲットが2つになります。

EC2 > ターゲットグループ > tg-ecs-nginx > Targets

構成は以下のようになります。

Internal ALB
    │
    ├── nginx Task 1
    └── nginx Task 2

ALBが2つのTaskへ負荷分散します。

CloudWatch Logsを確認する

CloudWatch Logsを開きます。

CloudWatch > Logs > Log groups > /ecs/nginx-task

ログストリームを開くと、Nginxのログを確認できます。

踏み台サーバーから何度かアクセスします。

curl http://<Internal ALBのDNS名>

ログが出力されれば、CloudWatch Logs連携も正常です。

Docker Composeとの違い

Docker Composeでは、基本的に1台のサーバー上でコンテナを起動します。

Docker Compose

Server
└── nginx

ECSでは、ServiceがTask数を維持します。

Amazon ECS

Cluster
└── Service
    ├── Task 1
    └── Task 2

Taskが停止しても、Serviceが指定された数に戻そうとします。

今回であれば、Desired tasksを2にしている場合、1つのTaskが停止しても、ECSが新しいTaskを起動しようとします。

ECSを利用するメリット

ECSを利用すると、以下のようなメリットがあります。

  • コンテナ障害時の自動復旧
  • Desired tasksによる簡単なスケールアウト
  • ALBとの連携
  • CloudWatch Logsとの統合
  • IAMによる権限制御
  • S3 FilesによるHTML更新の簡素化
  • Managed Instancesによるインスタンス管理負荷の軽減

まとめ

本記事では、Amazon ECS Managed Instancesを利用して、Nginxを構築しました。

また、HTMLファイルをDockerイメージに含めず、Amazon S3に保存し、S3 FilesでNginxコンテナへマウントしました。

S3 FilesをECSで利用するには、S3バケットだけでなく、S3 Filesファイルシステム、mount target、Task IAM Role、Security Groupの設定が必要です。

Amazon ECSは、簡単にコンテナ環境を構築・運用でき、スケールもできるため、従来のDocker環境に比べ本番運用に適しています。

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