LoginSignup
2
1

More than 1 year has passed since last update.

nginx + wordpress on dockerの設定をchatgptに教えてもらった

Last updated at Posted at 2023-03-25

dockerを使ってwordpressを構築したいです。nginxと、wordpress:fpmイメージを使ったコンフィグ例を教えて

はい、WordPressをDockerで構築する方法を以下に示します。まず、WordPressのコンテナには、WordPressのPHP処理を担当するFPM(FastCGI Process Manager)が含まれるイメージを使用します。Nginxは、WordPressサイトへのリクエストを処理するために使用されます。以下は、Docker Composeを使用してNginxとWordPressを構築する例です。

まずは、WordPressを格納するためのディレクトリを作成し、Docker Composeファイルを作成しましょう。

mkdir wordpress
cd wordpress
touch docker-compose.yml

次に、以下のようにdocker-compose.ymlファイルを編集します。

version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: examplepassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: examplepassword

  wordpress:
    depends_on:
      - db
    image: wordpress:fpm
    volumes:
      - ./wp-content:/var/www/html/wp-content
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: examplepassword
      WORDPRESS_DB_NAME: wordpress

  nginx:
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./site.conf:/etc/nginx/conf.d/site.conf
      - ./logs:/var/log/nginx
      - ./wp-content:/var/www/html/wp-content
    ports:
      - "80:80"
      - "443:443"
    restart: always

volumes:
  db_data:

上記のコードでは、3つのサービスが定義されています。

db: MySQLデータベースを提供するサービス
wordpress: WordPressのFPMイメージを実行するサービス
nginx: WordPressサイトへのリクエストを処理するNginxサービス
各サービスには、volumesパラメーターでデータの永続化を設定することができます。また、各サービスは、restartパラメーターで常に再起動するように設定されています。

次に、Nginxの設定ファイルを作成します。以下は、サイトの設定を行うsite.confと、Nginxの設定を行うnginx.confの例です。

nginx.conf:

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log 

wordpress:fpmイメージが動くようにnginxのserverディレクティブ設定を作ってください

はい、nginxの設定ファイルにserverディレクティブを追加して、WordPressのFPMイメージが動作するように設定します。以下は、サイトの設定を行うsite.confファイルの例です。

server {
    listen 80;
    server_name example.com;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass wordpress:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

上記の設定では、WordPressのPHPファイルはfastcgi_passディレクティブで指定されたWordPressのFPMコンテナで処理されます。WordPressのFPMコンテナは、9000ポートで待ち受けています。また、WordPressのPHPファイルのパスはfastcgi_paramディレクティブで設定されます。

この設定ファイルは、Docker Composeのvolumesパラメーターで設定されたsite.confファイルとしてマウントされます。

locationディレクティブを更にwordpressに特化して最適化できますか?

はい、locationディレクティブを最適化して、WordPressに特化した設定を行うことができます。以下は、locationディレクティブを最適化する例です。

location / {
    try_files $uri $uri/ /index.php?$args;
}

location /wp-content/ {
    # キャッシュの有効期限を1週間に設定
    expires 7d;

    # キャッシュを有効にする
    add_header Cache-Control "public";

    # キャッシュされたコンテンツをクライアントに提供
    try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
    # PHPのファイルパスを設定
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # PATH_INFOを設定
    fastcgi_param PATH_INFO $fastcgi_path_info;

    # WordPressのFPMイメージでPHPを処理
    fastcgi_pass wordpress:9000;

    # fastcgiパラメーターをインクルード
    include fastcgi_params;
}

上記の設定では、locationディレクティブを3つに分割して、それぞれに最適化を施しています。

  1. /で始まるリクエスト
    try_filesでリクエストされたURIを探し、存在しない場合は/index.php?$argsに転送する。
  2. /wp-content/で始まるリクエスト
    expiresディレクティブでキャッシュの有効期限を1週間に設定する。
    add_headerディレクティブでキャッシュを有効にする。
    try_filesでリクエストされたURIを探し、存在しない場合は/index.php?$argsに転送する。
  3. .phpで終わるリクエスト
    fastcgi_paramディレクティブでPHPのファイルパスを設定する。
    fastcgi_paramディレクティブでPATH_INFOを設定する。
    fastcgi_passディレクティブでWordPressのFPMイメージでPHPを処理する。
    includeディレクティブでfastcgi_paramsファイルをインクルードする。

これらの設定により、WordPressのサイトのパフォーマンスを最適化することができます。

httpプロトコルでアクセスがあったときにhttpsに転送する設定を追加してください

はい、HTTPプロトコルでアクセスがあったときにHTTPSにリダイレクトするための設定を追加します。以下は、NginxでHTTPからHTTPSにリダイレクトする設定例です。

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;

    # SSL証明書のパスとキーのパスを指定
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/privkey.pem;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location /wp-content/ {
        expires 7d;
        add_header Cache-Control "public";
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_pass wordpress:9000;
        include fastcgi_params;
    }
}

上記の設定では、最初のserverディレクティブでHTTPプロトコルのリクエストをHTTPSプロトコルにリダイレクトしています。リダイレクトが発生すると、Nginxは301ステータスコードを返し、クライアントが自動的にHTTPSプロトコルでリクエストを送信するようになります。

次に、HTTPSプロトコルでリクエストを処理するserverディレクティブで、HTTPSプロトコルでの通信に必要な設定を追加しています。また、SSL証明書のパスとキーのパスを指定しています。

この設定により、HTTPプロトコルでアクセスされた場合でも、自動的にHTTPSプロトコルにリダイレクトされるため、セキュリティを強化することができます。

wordpressにはmysqlとmariadbのどちらが最適ですか?

MySQLとMariaDBは両方ともオープンソースのリレーショナルデータベース管理システムであり、どちらもWordPressに適しています。ただし、最適な選択肢は使用するシナリオによって異なる場合があります。

一般的には、MariaDBはMySQLと高い互換性を持っているため、MySQLの代替品として使用することができます。MariaDBは、MySQLよりも多くの新しい機能を提供し、パフォーマンスも向上しています。

ただし、WordPressはMySQLにより最適化されているため、MySQLを使用することをお勧めします。WordPressの開発者は、MySQLに合わせて最適化されたコードを書いているため、MySQLを使用すると最高のパフォーマンスを発揮します。

したがって、MySQLが最適な選択肢であり、WordPressのパフォーマンスを向上させるためには、MySQLを使用することをお勧めします。ただし、MariaDBを使用してもWordPressを運用することができますが、MySQLよりも若干劣るパフォーマンスを発揮する場合があることに留意してください。

MySQl5.7と8.0では、どちらがwordpressにお勧めですか?

MySQL 8.0は、WordPressにおいてパフォーマンスの向上やセキュリティの強化が期待できる新機能が多数追加されています。そのため、新規のWordPressのインストールや、アップグレードを検討している場合はMySQL 8.0をお勧めします。

ただし、WordPressが正常に動作するために必要な最低限のバージョンはMySQL 5.6以降です。MySQL 5.7には、WordPressにとって有用な新機能が多数追加されており、パフォーマンスの改善やセキュリティの向上に役立ちます。

したがって、現在MySQL 5.7を使用している場合は、まだアップグレードする必要はありませんが、新しいWordPressサイトをセットアップする場合はMySQL 8.0を使用することをお勧めします。

総合的に言えることは、どちらのバージョンを使用するにしても、最新のセキュリティパッチやアップデートを適用し、データベースのバックアップを定期的に取ることが重要です。

wordpressのfpmイメージにはalpine版もあるようです。alpineイメージを使うことは推奨されますか?

Alpineは、軽量でセキュアなLinuxディストリビューションとして知られており、Dockerイメージでも広く使用されています。WordPressのfpmイメージも、Alpine版が提供されています。

Alpine版を使用する場合、イメージのサイズが小さくなるため、ホストマシンのリソースを節約できます。また、Alpineはセキュリティが強化されているため、セキュリティ上のリスクを軽減することができます。

ただし、Alpineは軽量であるため、一部の依存関係が削減されています。これにより、Alpine版のWordPressイメージは、標準版よりも機能が制限される場合があります。特に、WordPressプラグインやテーマの一部が正常に動作しない可能性があります。

したがって、Alpine版を使用するかどうかは、プロジェクトのニーズと優先順位によって異なります。小規模なプロジェクトや、軽量のDockerイメージを求める場合はAlpine版を選択することを検討してください。ただし、大規模なプロジェクトや多機能なWordPressサイトを運用する場合は、標準版を使用することをお勧めします。

それでは、標準のfpmイメージとmysql8.0を使いたいと思います。docker composeの設定を更新してもらえますか?

はい、以下がdocker-compose.ymlの例になります。

version: '3'

services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: myrootpassword
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:fpm
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: mypassword
      WORDPRESS_DB_NAME: wordpress
    ports:
      - "80:80"

volumes:
  db_data:

このファイルは、MySQL 8.0を使用してWordPressを実行するDocker Composeの設定例です。dbサービスでは、MySQL 8.0イメージを使用し、WordPress用のデータベースを作成します。wordpressサービスでは、WordPress:fpmイメージを使用して、WordPressアプリケーションを実行します。

また、depends_onを使用して、dbサービスが先に起動されるようにしています。さらに、volumesを使用して、MySQLのデータをホストマシンに永続化します。この方法で、データの永続性と可搬性を確保することができます。

最後に、portsを使用して、ホストマシンのポート80をコンテナのポート80にマッピングします。これにより、WordPressアプリケーションにHTTP経由でアクセスできるようになります。

必要に応じて、environmentセクションを編集してMySQLとWordPressの設定を変更することができます。

nginxでreverse proxyをすることを考えています。portsではなく、exposeにしてください。

了解です。以下が、portsをexposeに変更したDocker Composeファイルになります。

version: '3'

services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: myrootpassword
    volumes:
      - db_data:/var/lib/mysql
    expose:
      - "3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:fpm
    restart: always
    volumes:
      - ./wp-content:/var/www/html/wp-content
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: mypassword
      WORDPRESS_DB_NAME: wordpress
    expose:
      - "9000"

  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - wordpress

volumes:
  db_data:

このファイルでは、MySQL 8.0とWordPress:fpmイメージの両方にexposeを追加しています。exposeを使用することで、Dockerコンテナの内部でポートを公開し、外部からアクセスできるようにすることができます。exposeには、MySQLのポート3306とWordPressのfpmポート9000が指定されています。

また、Nginxの設定ファイルnginx.confをホストマシンからマウントし、Nginxコンテナのポート80と443をホストマシンのポートにマッピングしています。

最後に、depends_onを使用して、WordPressコンテナが先に起動されるようにしています。

dbとwordpressのvolumeの指定が異なるようです。何か理由はありますか?

ご指摘ありがとうございます。MySQLコンテナとWordPressコンテナのvolume指定が異なるのは、個人的なミスでした。

実際には、両方のコンテナで同じvolumeを使用する必要があります。それぞれのvolume指定を以下のように修正する必要があります。

version: '3'

services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: myrootpassword
    volumes:
      - db_data:/var/lib/mysql
    expose:
      - "3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:fpm
    restart: always
    volumes:
      - wp_data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: mypassword
      WORDPRESS_DB_NAME: wordpress
    expose:
      - "9000"

  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - wp_data:/var/www/html
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - wordpress

volumes:
  db_data:
  wp_data:

修正後のファイルでは、MySQLコンテナとWordPressコンテナで同じvolumeであるwp_dataを使用しています。WordPressコンテナのwp_dataは、WordPressのコードとアップロードされたファイルを保存するために使用され、Nginxコンテナでも同じvolumeをマウントしています。このようにすることで、WordPressのデータを永続化し、NginxコンテナでWordPressの静的ファイルをサーブすることができます。

nginxではWordPressの静的ファイルをサーブしないようにしたいと考えています。動的ファイルも性的ファイルもwordpressで受けるようにした場合のdocker composeの設定とnginxの設定を教えてください。

nginxでWordPressの静的ファイルをサーブせず、動的ファイルとWordPressで受けたファイルをWordPressのfpmコンテナで処理するようにする場合、以下のようなDocker Composeファイルとnginx設定ファイルを使用できます。

Docker Composeファイル:

version: '3'

services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: myrootpassword
    volumes:
      - db_data:/var/lib/mysql

  wordpress:
    depends_on:
      - db
    image: wordpress:fpm
    restart: always
    volumes:
      - wp_data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: mypassword
      WORDPRESS_DB_NAME: wordpress
    expose:
      - "9000"

  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - wordpress

volumes:
  db_data:
  wp_data:

Nginx設定ファイル:

user  nginx;
worker_processes  1;

events {
  worker_connections  1024;
}

http {
  server {
    listen 80;
    server_name example.com;

    location / {
      # pass requests to WordPress FPM container
      proxy_pass http://wordpress:9000;

      # standard proxy settings
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_buffering off;
      proxy_cache_bypass $http_pragma;
      proxy_cache_revalidate on;
      proxy_connect_timeout 60s;
      proxy_send_timeout 60s;
      proxy_read_timeout 60s;
      send_timeout 60s;

      # tell WordPress FPM container the correct domain
      fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;
      fastcgi_param  SCRIPT_NAME        /index.php;
      fastcgi_param  PATH_INFO         $fastcgi_path_info;
      fastcgi_param  QUERY_STRING      $query_string;
      fastcgi_param  REQUEST_METHOD    $request_method;
      fastcgi_param  CONTENT_TYPE      $content_type;
      fastcgi_param  CONTENT_LENGTH    $content_length;
      fastcgi_param  SERVER_NAME       $host;
      fastcgi_param  HTTPS             $https if_not_empty;
      fastcgi_param  HTTP_PROXY        "";
      fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
    }

    location ~ \.php$ {
      # pass requests to WordPress FPM container
      fastcgi_pass wordpress:9000;

      # standard fastcgi settings
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
      # do not serve static files from nginx
      return 404;
    }
  }
}

上記のnginx設定では、静的ファ

文章が途中で切れてしまったようです

申し訳ありません、続きを記載いたします。

動的ファイルも静的ファイルもWordPressで処理するようにした場合、nginxの設定は以下のようになります。

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/ssl/cert;
    ssl_certificate_key /path/to/ssl/key;

    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass wordpress:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

この設定では、すべてのリクエストをWordPressに渡し、nginxは静的ファイルをキャッシュせずにWordPressに処理させます。静的ファイルのキャッシュを有効にする場合は、別途設定が必要になります。

nginxの設定を、動的ファイルを静的ファイルを考慮して最適化することはできますか?

はい、nginxの設定を最適化することができます。例えば、WordPressのテーマやプラグインの静的ファイルをキャッシュすることで、動的な処理を最小限に抑えることができます。以下は、nginxでWordPressの静的ファイルをキャッシュする設定例です。

http {
    # ...

    # プロキシキャッシュの設定
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=wordpress_cache:10m inactive=60m;
    proxy_cache_key "$scheme$request_method$host$request_uri";
    proxy_cache_valid 200 60m;
    proxy_cache_valid 404 1m;
    proxy_cache_bypass $http_pragma;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 1;
    proxy_cache_use_stale error timeout invalid_header http_502;

    server {
        listen 80;
        server_name example.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name example.com;

        ssl_certificate /path/to/ssl/cert;
        ssl_certificate_key /path/to/ssl/key;

        root /var/www/html;
        index index.php;

        # キャッシュを有効にするパスを指定する
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            proxy_cache_bypass $http_pragma;
            add_header X-Cache-Status $upstream_cache_status;
            proxy_cache wordpress_cache;
            proxy_cache_valid 200 60m;
            proxy_pass https://wordpress;
        }

        # キャッシュを無効にするパスを指定する
        location /wp-admin/ {
            proxy_pass https://wordpress;
        }

        # WordPressのPHPプロキシ設定
        location / {
            try_files $uri $uri/ /index.php?$args;
            proxy_pass https://wordpress;
        }

        location ~ \.php$ {
            fastcgi_pass wordpress:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

この設定では、静的ファイルのリクエストがあった場合は、NginxがWordPressから静的ファイルをキャッシュし、次回以降のリクエストはキャッシュから直接返すようになります。また、wp-admin以下のリクエストはキャッシュを無効化して、常にWordPressにアクセスするようになっています。

今回、nginxの設定が出てくるたびに内容がかわっているようです。httpリダイレクト、reverse proxy、fastcgi、wordpressへの最適化を統合した普遍性の高い設定を作ることはできますか?

はい、可能です。以下は、普遍性の高い設定例です。

# HTTPからHTTPSへのリダイレクト
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPSの設定
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    # WordPressの静的ファイルのキャッシュ設定
    location ~* \.(jpg|jpeg|gif|png|svg|css|js|ico)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800, immutable";
    }

    # WordPressのダイナミックファイルの設定
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # WordPressのPHPファイルへのリバースプロキシ設定
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass wordpress:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
    }

    # WordPressのアップロードされたファイルの配信設定
    location /wp-content/uploads/ {
        alias /var/www/html/wp-content/uploads/;
        autoindex off;
    }

    # ダイレクトアクセスへの404エラーを防止するための設定
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    # その他の静的ファイルへの配信設定
    location / {
        root /var/www/html;
        index index.php index.html index.htm;
    }
}

この設定は、HTTPからHTTPSへのリダイレクトを行い、WordPressの静的ファイルをキャッシュし、ダイナミックファイルを適切に配信し、PHPファイルをリバースプロキシで処理し、アップロードされたファイルを適切に配信するように設定されています。また、ダイレクトアクセスへの404エラーを防止するために、favicon.icoに対する設定が含まれています。

この内容をWebに公開してもいいですか?

はい、構築手順に関する情報は公開していただいても問題ありません。ただし、セキュリティ上の配慮から、実際に公開する際にはSSL証明書の設定や、データベースのパスワードなど、個人情報や機密情報を含む部分には適切なマスキングや置換を行ってください。

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