/** * WPML compatibility functions * * @global array $duplicated_posts Array to store the posts being duplicated. * * @package Yoast\WP\Duplicate_Post * @since 3.2 */ add_action( 'admin_init', 'duplicate_post_wpml_init' ); /** * Add handlers for WPML compatibility. */ function duplicate_post_wpml_init() { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { add_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'shutdown', 'duplicate_wpml_string_packages', 11 ); } } global $duplicated_posts; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break. $duplicated_posts = []; /** * Copy post translations. * * @global SitePress $sitepress Instance of the Main WPML class. * @global array $duplicated_posts Array of duplicated posts. * * @param int $post_id ID of the copy. * @param WP_Post $post Original post object. * @param string $status Status of the new post. */ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' ) { global $sitepress; global $duplicated_posts; remove_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10 ); remove_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10 ); $current_language = $sitepress->get_current_language(); $trid = $sitepress->get_element_trid( $post->ID ); if ( ! empty( $trid ) ) { $translations = $sitepress->get_element_translations( $trid ); $new_trid = $sitepress->get_element_trid( $post_id ); foreach ( $translations as $code => $details ) { if ( $code !== $current_language ) { if ( $details->element_id ) { $translation = get_post( $details->element_id ); if ( ! $translation ) { continue; } $new_post_id = duplicate_post_create_duplicate( $translation, $status ); if ( ! is_wp_error( $new_post_id ) ) { $sitepress->set_element_language_details( $new_post_id, 'post_' . $translation->post_type, $new_trid, $code, $current_language ); } } } } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above. $duplicated_posts[ $post->ID ] = $post_id; } } /** * Duplicate string packages. * * @global array() $duplicated_posts Array of duplicated posts. */ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break. global $duplicated_posts; foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); if ( is_array( $original_string_packages ) ) { foreach ( $original_string_packages as $original_string_package ) { $translated_original_strings = $original_string_package->get_translated_strings( [] ); foreach ( $new_string_packages as $new_string_package ) { $cache = new WPML_WP_Cache( 'WPML_Package' ); $cache->flush_group_cache(); $new_strings = $new_string_package->get_package_strings(); foreach ( $new_strings as $new_string ) { if ( isset( $translated_original_strings[ $new_string->name ] ) ) { foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) { do_action( // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. 'wpml_add_string_translation', $new_string->id, $language, $translated_string['value'], $translated_string['status'] ); } } } } } } } } 本番nlq-dev 設定 – Raqqa

本番nlq-dev 設定

nlq-dev-web-publish固定IP を向いていました。

  • 旧: tcp:172.19.0.7:5174
  • 実際の web: 172.19.0.6:5174

そのため nginx は 127.0.0.1:5174 に投げても、その先の socat が古いIPへ転送して 502 になっていました。


現在の正常状態

これが正常です。

docker inspect nlq-dev-web-publish --format '{{json .Config.Cmd}}'
["tcp-listen:5174,fork,reuseaddr","tcp:172.19.0.6:5174"]

nginx はこのままでOKです。

location / {
proxy_pass http://127.0.0.1:5174/;
proxy_http_version 1.1; proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}

次回 502 が出たときの確認コマンド

これを順番に貼れば十分です。

docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
docker inspect nlq-dev-web-publish --format '{{json .Config.Cmd}}'
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nlq-dev-web-1
docker logs --tail 50 nlq-dev-web-publish
docker logs --tail 50 nlq-dev-nginx
docker logs --tail 50 nlq-dev-web-1

見るポイントはこれです。

  • nlq-dev-web-publishtcp:<IP>:5174
  • nlq-dev-web-1 の現在IP
  • この2つが一致しているか

復旧手順

一致していなければ、これで直せます。

WEB_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nlq-dev-web-1)
echo "$WEB_IP"docker rm -f nlq-dev-web-publish 2>/dev/null || truedocker run -d \
--name nlq-dev-web-publish \
--restart unless-stopped \
--network host \
alpine/socat \
tcp-listen:5174,fork,reuseaddr tcp:${WEB_IP}:5174docker restart nlq-dev-nginx

確認:

docker inspect nlq-dev-web-publish --format '{{json .Config.Cmd}}'
docker logs --tail 20 nlq-dev-web-publish
docker logs --tail 20 nlq-dev-nginx

毎回これをやらないための設定

いまの構成は 固定IP依存 なので、nlq-dev-web-1 が再起動してIPが変わるとまた起きます。

なので恒久対応はどちらかです。

方法A: 手順書として残す

一番簡単です。
nlq-dev-web-1 を再起動したら、必ず nlq-dev-web-publish を作り直す。

方法B: スクリプト化する

これがおすすめです。
たとえば /opt/nlq-dev/scripts/recreate-web-publish.sh を作ります。

cat > /opt/nlq-dev/scripts/recreate-web-publish.sh <<'EOF'
#!/usr/bin/env bash
set -euWEB_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nlq-dev-web-1)echo "WEB_IP=${WEB_IP}"docker rm -f nlq-dev-web-publish 2>/dev/null || truedocker run -d \
--name nlq-dev-web-publish \
--restart unless-stopped \
--network host \
alpine/socat \
tcp-listen:5174,fork,reuseaddr tcp:${WEB_IP}:5174docker restart nlq-dev-nginxdocker inspect nlq-dev-web-publish --format '{{json .Config.Cmd}}'
EOFchmod +x /opt/nlq-dev/scripts/recreate-web-publish.sh

以後はこれだけです。

/opt/nlq-dev/scripts/recreate-web-publish.sh

さらによい恒久対応

本当は web-publish固定IPではなく名前ベース にしたいです。
ただ、今の構成だと host network の socat から bridge network 上の nlq-dev-web-1 名を直接引けないことが多いので、すぐ効くのは上のスクリプト化です。


今回のメモ

  • nlq-dev-nginx127.0.0.1:5174 を見る
  • 127.0.0.1:5174 の実体は nlq-dev-web-publish
  • nlq-dev-web-publishalpine/socat
  • nlq-dev-web-publish は compose 管理外
  • nlq-dev-web-1 再起動でIPが変わると、nlq-dev-web-publish が stale になる
  • stale になると 502

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です