PHP7のDockerイメージをカスタマイズして使っていたら、apt updateでエラーになる

前提

以下のような、Dockerfileとcompose.ymlを使った環境がある

Dockerfile

FROM php:7.2.11-apache

# Install MySQL Extention
RUN docker-php-ext-install mysqli pdo_mysql

# Install GD Extention
RUN apt update && apt install -y \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng-dev \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

compose.yml

services:
  server:
    build:
      context: .
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html
  db:
    image: mysql:5.7
    user: root
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db-password
      - MYSQL_DATABASE=example
    ports:
      - 3306:3306
volumes:
  db-data:
secrets:
  db-password:
    file: password.txt

ディレクトリ構成

$ tree
.
├── Dockerfile
├── compose.yml
├── password.txt
└── src
    └── index.php

状況

docker compose buildをすると

$ docker compose build
[+] Building 15.2s (6/6) FINISHED                                                                                                                                                                             docker:default
 => [server internal] load build definition from Dockerfile                                                                                                                                                             0.3s
 => => transferring dockerfile: 411B                                                                                                                                                                                    0.0s
 => [server internal] load .dockerignore                                                                                                                                                                                0.2s
 => => transferring context: 2B                                                                                                                                                                                         0.0s
 => [server internal] load metadata for docker.io/library/php:7.2.11-apache                                                                                                                                             0.0s
 => [server 1/3] FROM docker.io/library/php:7.2.11-apache                                                                                                                                                               0.0s
 => CACHED [server 2/3] RUN docker-php-ext-install mysqli pdo_mysql                                                                                                                                                     0.0s
 => ERROR [server 3/3] RUN apt-get update && apt-get install -y     libfreetype6-dev     libjpeg62-turbo-dev     libpng-dev     && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr  13.6s
------
 > [server 3/3] RUN apt-get update && apt-get install -y     libfreetype6-dev     libjpeg62-turbo-dev     libpng-dev     && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/     && docker-php-ext-install -j$(nproc) gd:
1.330 Ign:1 http://security.debian.org/debian-security stretch/updates InRelease
1.589 Ign:2 http://deb.debian.org/debian stretch InRelease
:
:
:
3.902 Err:8 http://security.debian.org/debian-security stretch/updates/main amd64 Packages
3.902   404  Not Found [IP: 151.101.194.132 80]
:
:
:
11.67 Err:16 http://deb.debian.org/debian stretch/main amd64 Packages
11.67   404  Not Found
:
12.54 Err:18 http://deb.debian.org/debian stretch-updates/main amd64 Packages
12.54   404  Not Found
12.55 Fetched 8706 kB in 11s (772 kB/s)
12.55 Reading package lists...
13.01 W: The repository 'http://security.debian.org/debian-security stretch/updates Release' does not have a Release file.
13.01 W: GPG error: http://security.debian.org/debian-security buster/updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 112695A0E562B32A NO_PUBKEY 54404762BBB6E853
13.01 W: The repository 'http://security.debian.org/debian-security buster/updates InRelease' is not signed.
13.01 W: GPG error: http://deb.debian.org/debian buster InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY DCC9EFBF77E11517
13.01 W: The repository 'http://deb.debian.org/debian buster InRelease' is not signed.
13.01 W: GPG error: http://deb.debian.org/debian buster-updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9
13.01 W: The repository 'http://deb.debian.org/debian buster-updates InRelease' is not signed.
13.01 W: The repository 'http://deb.debian.org/debian stretch Release' does not have a Release file.
13.01 W: The repository 'http://deb.debian.org/debian stretch-updates Release' does not have a Release file.
13.01 E: Failed to fetch http://security.debian.org/debian-security/dists/stretch/updates/main/binary-amd64/Packages  404  Not Found [IP: 151.101.194.132 80]
13.01 E: Failed to fetch http://deb.debian.org/debian/dists/stretch/main/binary-amd64/Packages  404  Not Found
13.01 E: Failed to fetch http://deb.debian.org/debian/dists/stretch-updates/main/binary-amd64/Packages  404  Not Found
13.01 E: Some index files failed to download. They have been ignored, or old ones used instead.
------
failed to solve: process "/bin/sh -c apt-get update && apt-get install -y     libfreetype6-dev     libjpeg62-turbo-dev     libpng-dev     && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/     && docker-php-ext-install -j$(nproc) gd" did not complete successfully: exit code: 100

エラー内容から http://deb.debian.org/debian にアクセスすると、dists以下にstretchが見つからない。

【Debianサポート終了】Google Cloud RunにDockerfileを使ってデプロイしようとしたらエラーが出た によると、Debian 9.0(stretch)のサポートが2022年6月30日で終了したため、パッケージリポジトリは http://archive.debian.org に移動したとのこと。

そのため、Dockerfile内でapt updateをすると、エラーとなってしまっていた。

そこで、PHPイメージ内の/etc/apt/source.listにあるURLを書き換える。

対応

書き換え前

# cat /etc/apt/sources.list
deb http://deb.debian.org/debian stretch main
deb http://security.debian.org/debian-security stretch/updates main
deb http://deb.debian.org/debian stretch-updates main

http://deb.debian.org , http://security.debian.orghttp://archive.debian.org に変更する。 また、スイートのstretch-updatesはなくなったため削除する。

sed -i -e 's#deb.debian.org#archive.debian.org#' -e 's#security.debian.org#archive.debian.org#' -e '/stretch-updates/d' /etc/apt/sources.list

この状態でapt udpateを実行すると、/etc/apt/sources.list.d/buster.listNO_PUBKEY エラーが発生する。

# apt update
Get:1 http://deb.debian.org/debian buster InRelease [122 kB]
Err:1 http://deb.debian.org/debian buster InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY DCC9EFBF77E11517
Get:2 http://deb.debian.org/debian buster-updates InRelease [56.6 kB]
Err:2 http://deb.debian.org/debian buster-updates InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9
Get:3 http://security.debian.org/debian-security buster/updates InRelease [34.8 kB]
Err:3 http://security.debian.org/debian-security buster/updates InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 112695A0E562B32A NO_PUBKEY 54404762BBB6E853
Ign:4 http://archive.debian.org/debian stretch InRelease
Get:5 http://archive.debian.org/debian-security stretch/updates InRelease [59.1 kB]
Get:6 http://archive.debian.org/debian stretch Release [118 kB]
Get:7 http://archive.debian.org/debian stretch Release.gpg [3177 B]
Get:8 http://archive.debian.org/debian-security stretch/updates/main amd64 Packages [782 kB]
Get:9 http://archive.debian.org/debian stretch/main amd64 Packages [7080 kB]
Reading package lists... Done
W: GPG error: http://deb.debian.org/debian buster InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY DCC9EFBF77E11517
E: The repository 'http://deb.debian.org/debian buster InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://deb.debian.org/debian buster-updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 648ACFD622F3D138 NO_PUBKEY 0E98404D386FA1D9
E: The repository 'http://deb.debian.org/debian buster-updates InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
W: GPG error: http://security.debian.org/debian-security buster/updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 112695A0E562B32A NO_PUBKEY 54404762BBB6E853
E: The repository 'http://security.debian.org/debian-security buster/updates InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

/etc/apt/sources.list.d/buster.listを削除しても今回の場合問題ないが、そのままにしておく場合、debian-archive-keyringをインストールする

# apt update
# apt install -y debian-archive-keyring 

apt updateもすべて成功する

# apt update
Get:1 http://security.debian.org/debian-security buster/updates InRelease [34.8 kB]
:
:
:
Reading package lists... Done
Building dependency tree
Reading state information... Done
71 packages can be upgraded. Run 'apt list --upgradable' to see them.

最終的なDockerfileは

  • /etc/apt/sources.list.d/buster.listをなくした場合
@@ -1,5 +1,8 @@
 FROM php:7.2.11-apache

+RUN sed -i -e 's#deb.debian.org#archive.debian.org#' -e 's#security.debian.org#archive.debian.org#' -e '/stretch-updates/d' /etc/apt/sources.list \
+    && rm /etc/apt/sources.list.d/buster.list
+
 # Install MySQL Extention
 RUN docker-php-ext-install mysqli pdo_mysql
  • /etc/apt/sources.list.d/buster.listを残す場合
@@ -1,5 +1,13 @@
 FROM php:7.2.11-apache

+RUN sed -i -e 's#deb.debian.org#archive.debian.org#' -e 's#security.debian.org#archive.debian.org#' -e '/stretch-updates/d' /etc/apt/sources.list \
+    && mv /etc/apt/sources.list.d/buster.list /etc/apt/sources.list.d/buster.list.disabled \
+    && apt update \
+    && apt install -y debian-archive-keyring \
+    && mv /etc/apt/sources.list.d/buster.list.disabled /etc/apt/sources.list.d/buster.list \
+    && apt-get clean \
+    && rm -rf /var/lib/apt/lists/*
+
 # Install MySQL Extention
 RUN docker-php-ext-install mysqli pdo_mysql

debian stretchを使っていることを明確にするためにベースイメージをphp:7.2.11-apache-stretch変更しても可能でした

参考

Apache 2.4.54とPHP 5.2.17のDockerイメージを作る

  • Apache 2.4.54 と PHP 5.2.17 の Docker イメージがオフィシャルでなかったのでソースをビルドする形でイメージを作成する
  • PHP 5.2 は古いため、ビルドの際の依存パッケージのバージョンも古いほうがいいと思ったので、ベースの OS は、Ubuntu14.04 を使うことにした
  • マルチステージビルドでサイズを減らした
  • PHP はデフォルトに加え以下のモジュールを組み込む
    • GD(jpeg,png,freetype2)
    • mbstring
    • MySQL
    • PDO MySQL
    • MySQLi
    • zlib
    • OpenSSL
    • cURL
    • hash
    • mhash
    • mcrypt
    • zip

作成した Dockerfile 一式(Dockerfile と PHP のソースコードに適用するパッチが3つ)

--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -328,10 +328,12 @@ static inline int php_openssl_setup_cryp
sslsock->is_client = 1;
method = SSLv23_client_method();
break;
+#ifndef OPENSSL_NO_SSL2
case STREAM_CRYPTO_METHOD_SSLv2_CLIENT:
sslsock->is_client = 1;
method = SSLv2_client_method();
break;
+#endif
case STREAM_CRYPTO_METHOD_SSLv3_CLIENT:
sslsock->is_client = 1;
method = SSLv3_client_method();
@@ -348,10 +350,12 @@ static inline int php_openssl_setup_cryp
sslsock->is_client = 0;
method = SSLv3_server_method();
break;
+#ifndef OPENSSL_NO_SSL2
case STREAM_CRYPTO_METHOD_SSLv2_SERVER:
sslsock->is_client = 0;
method = SSLv2_server_method();
break;
+#endif
case STREAM_CRYPTO_METHOD_TLS_SERVER:
sslsock->is_client = 0;
method = TLSv1_server_method();
@@ -629,9 +633,11 @@ static inline int php_openssl_tcp_sockop
case STREAM_CRYPTO_METHOD_SSLv23_CLIENT:
sock->method = STREAM_CRYPTO_METHOD_SSLv23_SERVER;
break;
+#ifndef OPENSSL_NO_SSL2
case STREAM_CRYPTO_METHOD_SSLv2_CLIENT:
sock->method = STREAM_CRYPTO_METHOD_SSLv2_SERVER;
break;
+#endif
case STREAM_CRYPTO_METHOD_SSLv3_CLIENT:
sock->method = STREAM_CRYPTO_METHOD_SSLv3_SERVER;
break;
@@ -911,9 +917,11 @@ php_stream *php_openssl_ssl_socket_facto
if (strncmp(proto, "ssl", protolen) == 0) {
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+#ifndef OPENSSL_NO_SSL2
} else if (strncmp(proto, "sslv2", protolen) == 0) {
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv2_CLIENT;
+#endif
} else if (strncmp(proto, "sslv3", protolen) == 0) {
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
# ビルドステージ
FROM ubuntu:14.04 as build
# ビルドに必要なもの
ENV BUILD_DEPENDENCIES curl make patch
RUN apt update && apt install -y $BUILD_DEPENDENCIES && rm -r /var/lib/apt/lists/*
ENV SOURCE_DIR /usr/local/src
# Apacheビルド
ENV APACHE_BUILD_DEPENDENCIES libapr1-dev libaprutil1-dev
ENV APACHE_SOURCE_DIR $SOURCE_DIR/httpd
RUN set -eux \
# 依存パッケージインストール
&& apt update && apt install -y $APACHE_BUILD_DEPENDENCIES \
# ソースコードダウンロード・展開
&& cd $SOURCE_DIR \
&& curl -SL https://archive.apache.org/dist/httpd/httpd-2.4.54.tar.gz -o httpd.tar.gz \
&& mkdir -p $APACHE_SOURCE_DIR \
&& tar -xf httpd.tar.gz -C $APACHE_SOURCE_DIR --strip-components=1 \
# configure, make
&& cd httpd \
&& ./configure --enable-so \
&& make -j"$(nproc)" \
# インストール
&& make install \
# ビルドファイル、依存パッケージ削除
&& rm -r $SOURCE_DIR/httpd.tar.gz $APACHE_SOURCE_DIR \
&& apt remove -y $APACHE_BUILD_DEPENDENCIES \
&& apt-get autoremove -y && rm -r /var/lib/apt/lists/*
# PHP設定ファイルディレクトリを作成
ENV PHP_BUILD_DEPENDENCIES libapr1-dev libaprutil1-dev \
libxml2-dev libcurl4-openssl-dev libjpeg-dev \
libpng12-dev libfreetype6-dev libt1-dev libmcrypt-dev libmhash-dev libmysqlclient-dev libltdl7-dev
ENV PHP_SOURCE_DIR $SOURCE_DIR/php
ENV PHP_INI_DIR /usr/local/etc/php
RUN mkdir -p $PHP_INI_DIR/conf.d
# パッチをコピー
COPY patch/*.patch $PHP_SOURCE_DIR/
# PHPビルド
RUN set -eux \
# 依存パッケージインストール
&& apt update && apt install -y $PHP_BUILD_DEPENDENCIES \
# FreeType2インクルードファイルパス調整
&& mkdir -pv /usr/include/freetype2/freetype \
&& ln -sf /usr/include/freetype2/freetype.h /usr/include/freetype2/freetype/freetype.h \
# ソースコードダウンロード・展開
&& cd $SOURCE_DIR \
&& curl -SL "http://museum.php.net/php5/php-5.2.17.tar.bz2" -o php.tar.bz2 \
&& mkdir -p $PHP_SOURCE_DIR \
&& tar -xf php.tar.bz2 -C $PHP_SOURCE_DIR --strip-components=1 \
&& cd $PHP_SOURCE_DIR \
# パッチ
&& patch -p0 -b < $PHP_SOURCE_DIR/xml.patch \
&& patch -p1 -b < $PHP_SOURCE_DIR/debian_patches_disable_SSLv2_for_openssl_1_0_0.patch \
&& patch -l -p0 -b < $PHP_SOURCE_DIR/libphp5.so.patch \
# configure, make
&& ./configure \
--with-config-file-path=$PHP_INI_DIR \
--with-config-file-scan-dir=$PHP_INI_DIR/conf.d \
--with-libdir=lib/x86_64-linux-gnu \
--with-apxs2=/usr/local/apache2/bin/apxs \
--with-gd \
--with-png-dir=/usr/lib \
--with-jpeg-dir=/usr/lib \
--with-freetype-dir \
--enable-mbstring \
--with-mysql \
--with-mysqli \
--with-pdo-mysql \
--with-zlib \
--with-openssl \
--with-curl \
--with-mhash \
--with-mcrypt \
--enable-zip \
&& make -j"$(nproc)" \
# インストール
&& make install \
# 設定ファイルコピー
&& cp /usr/local/src/php/php.ini-recommended $PHP_INI_DIR/php.ini-recommended \
# # ビルドファイル、依存パッケージ削除
&& rm -r $SOURCE_DIR//php.tar.bz2 $PHP_SOURCE_DIR \
&& apt remove -y $PHP_BUILD_DEPENDENCIES \
&& apt-get autoremove -y && rm -r /var/lib/apt/lists/*
RUN apt remove -y $BUILD_DEPENDENCIES && apt-get autoremove -y && rm -r /var/lib/apt/lists/*
# ランタイムステージ
FROM ubuntu:14.04 as runtime
# 依存パッケージのインストール
ENV RUNTIME_DEPENDENCIES libapr1 libaprutil1 libcurl3 libxml2 libjpeg8 libfreetype6 \
libt1-5 libmcrypt4 libmhash2 libmysqlclient18
RUN apt update \
&& apt install -y $RUNTIME_DEPENDENCIES \
&& rm -r /var/lib/apt/lists/*
# 生成物コピー
COPY --from=build /usr/local /usr/local
# Apache設定
RUN set -eux \
&& cd / \
&& mkdir -p /var/www/html \
&& sed -i -r " \
s/(DirectoryIndex index[.])html/\1php index\.html/; \
s#/usr/local/apache2/htdocs#/var/www/html#g; \
s#^(\s*CustomLog)\s+\S+#\1 /proc/self/fd/1#g; \
s#^(\s*ErrorLog)\s+\S+#\1 /proc/self/fd/2#g; \
s/#LoadModule rewrite_module/LoadModule rewrite_module/g; \
/<Directory \"\/var\/www\/html\">/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/; \
$ a<FilesMatch \\.php$>\n\tSetHandler application/x-httpd-php\n</FilesMatch> \
" /usr/local/apache2/conf/httpd.conf \
&& echo "<html><head></head><body><?php echo '<h1>Hello, World!</h1>'; ?></body></html>" > /var/www/html/index.php
# PHP設定
ENV PHP_INI_DIR /usr/local/etc/php
RUN set -eux \
&& sed '/\;error_log = syslog/a error_log=/proc/1/fd/2' $PHP_INI_DIR/php.ini-recommended > $PHP_INI_DIR/php.ini
ENV PATH $PATH:/usr/local/apache2/bin
ENV PATH $PATH:/usr/local/bin/
WORKDIR /var/www/html
VOLUME /var/www/html
EXPOSE 80
CMD ["httpd", "-DFOREGROUND"]
view raw Dockerfile hosted with ❤ by GitHub
--- sapi/apache2handler/php_functions.c 2023-01-19 14:24:50.358748972 +0000
+++ sapi/apache2handler/php_functions.c 2023-01-19 14:24:34.889896546 +0000
@@ -383,7 +383,7 @@
char *p;
server_rec *serv = ((php_struct *) SG(server_context))->r->server;
#if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
- AP_DECLARE_DATA extern unixd_config_rec unixd_config;
+ AP_DECLARE_DATA extern unixd_config_rec ap_unixd_config;
#endif
for (n = 0; ap_loaded_modules[n]; ++n) {
@@ -414,7 +414,7 @@
php_info_print_table_row(2, "Hostname:Port", tmp);
#if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
- snprintf(tmp, sizeof(tmp), "%s(%d)/%d", unixd_config.user_name, unixd_config.user_id, unixd_config.group_id);
+ snprintf(tmp, sizeof(tmp), "%s(%d)/%d", ap_unixd_config.user_name, ap_unixd_config.user_id, ap_unixd_config.group_id);
php_info_print_table_row(2, "User/Group", tmp);
#endif
--- ext/dom/node.c 2012-08-06 17:49:48.826716692 +0800
+++ ext/dom/node.c 2012-08-06 17:52:47.633484660 +0800
@@ -1895,9 +1895,17 @@ static void dom_canonicalization(INTERNA
RETVAL_FALSE;
} else {
if (mode == 0) {
+#ifdef LIBXML2_NEW_BUFFER
+ ret = xmlOutputBufferGetSize(buf);
+#else
ret = buf->buffer->use;
+#endif
if (ret > 0) {
+#ifdef LIBXML2_NEW_BUFFER
+ RETVAL_STRINGL((char *) xmlOutputBufferGetContent(buf), ret, 1);
+#else
RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
+#endif
} else {
RETVAL_EMPTY_STRING();
}
--- ext/dom/documenttype.c 2012-08-06 18:02:16.019640870 +0800
+++ ext/dom/documenttype.c 2012-08-06 18:06:16.612228905 +0800
@@ -205,7 +205,13 @@ int dom_documenttype_internal_subset_rea
if (buff != NULL) {
xmlNodeDumpOutput (buff, NULL, (xmlNodePtr) intsubset, 0, 0, NULL);
xmlOutputBufferFlush(buff);
+
+#ifdef LIBXML2_NEW_BUFFER
+ ZVAL_STRINGL(*retval, xmlOutputBufferGetContent(buff),
+ xmlOutputBufferGetSize(buff), 1);
+#else
ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1);
+#endif
(void)xmlOutputBufferClose(buff);
return SUCCESS;
}
--- ext/simplexml/simplexml.c 2012-08-06 18:10:44.621017026 +0800
+++ ext/simplexml/simplexml.c 2012-08-06 18:12:48.016270419 +0800
@@ -1417,7 +1417,12 @@ SXE_METHOD(asXML)
xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding);
xmlOutputBufferFlush(outbuf);
+#ifdef LIBXML2_NEW_BUFFER
+ RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf),
+ xmlOutputBufferGetSize(outbuf), 1);
+#else
RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1);
+#endif
xmlOutputBufferClose(outbuf);
}
} else {
view raw xml.patch hosted with ❤ by GitHub

イメージを作成

ファイル構成は以下の通り

Dockerfile
patch/
      debian_patches_disable_SSLv2_for_openssl_1_0_0.patch
      libphp5.so.patch
      xml.patch

ビルド

$ docker build -t php:5.2.17-apache2.4.54 .

コンテナを実行

このイメージでは、HTTP ポートは 80 で公開

ドキュメントルートは /var/www/html に設定している

htdocs ディレクトリを作成、その下に index.php を作成して

<?php
phpinfo();

としておく

$ docker run --rm -v $(pwd)/htdocs:/var/www/html -p 80:80 php:5.2.17-apache2.4.54

http://localhost にアクセス

phpinfo

Docker Compose を使用する場合の compose.yaml サンプル

services:
  php:
    build:
      dockerfile: Dockerfile
    volumes:
      - ./htdocs:/var/www/html
    ports:
      - 80:80

トラブルシュート

イメージを作成するまでのトラブルシュート

configure のエラー

configure: error: libjpeg.(a|so) not found.

libjpeg.so の位置を確認すると

# find /usr/lib -name "libjpeg.a"
/usr/lib/x86_64-linux-gnu/libjpeg.a

phpbrew/README.ja.md at master · phpbrew/phpbrewより、

–with-libdir で参照先を lib/x86_64-linux-gnu にセットしたうえで、–with-jpeg-dir,–with-png-dir/usr/lib にセットする

# ./configure \
 (省略)
 --with-libdir=lib/x86_64-linux-gnu \
 --with-gd \
 --with-png-dir=/usr/lib \
 --with-jpeg-dir=/usr/lib

configure: error: freetype.h not found.

libfreetype6-dev をインストールののち、configure に –with-freetype-dir をつけているにもかかわらず上記エラーが発生

Configure php 5.3 fail with error : freetype.h not found (but libfreetype6-dev is installed) – Stack Overflowより、

freetype.h の位置を調整する

freetype.h はビルドの際に必要だが、実行時には PHP のビルド成果物と libfreetype6 があれば問題ない

# mkdir /usr/include/freetype2/freetype
# ln -s /usr/include/freetype2/freetype.h /usr/include/freetype2/freetype/freetype.h

make のエラー

ext/dom/node.c:1953:21: error: dereferencing pointer to incomplete type

/usr/local/src/php/ext/dom/node.c: In function 'dom_canonicalization':
/usr/local/src/php/ext/dom/node.c:1953:21: error: dereferencing pointer to incomplete type
    ret = buf->buffer->use;
                     ^
In file included from /usr/local/src/php/main/php.h:38:0,
                 from /usr/local/src/php/ext/dom/node.c:26:
/usr/local/src/php/ext/dom/node.c:1955:40: error: dereferencing pointer to incomplete type
     RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
                                        ^
/usr/local/src/php/Zend/zend_API.h:472:14: note: in definition of macro 'ZVAL_STRINGL'
   char *__s=(s); int __l=l;  \
              ^
/usr/local/src/php/ext/dom/node.c:1955:5: note: in expansion of macro 'RETVAL_STRINGL'
     RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
     ^
make: *** [ext/dom/node.lo] Error 1

CentOS7.1 に PHP5.2.17 環境を構築する – Qiitaより、パッチが公開されているので適用する

# cd /usr/local/src/php
# curl -ksSL "https://mail.gnome.org/archives/xml/2012-August/txtF4xf2MZKEQ.txt" -o xml.patch
# patch -p0 -b < xml.patch
patching file ext/dom/node.c
Hunk #1 succeeded at 1950 (offset 55 lines).
patching file ext/dom/documenttype.c
Hunk #1 succeeded at 215 (offset 10 lines).
patching file ext/simplexml/simplexml.c
Hunk #1 succeeded at 1343 (offset -74 lines).

ext/openssl/xp_ssl.c:337: undefined reference to `SSLv2_client_method’

ext/openssl/.libs/xp_ssl.o: In function `php_openssl_setup_crypto':
/usr/local/src/php/ext/openssl/xp_ssl.c:337: undefined reference to `SSLv2_client_method'
/usr/local/src/php/ext/openssl/xp_ssl.c:357: undefined reference to `SSLv2_server_method'
collect2: error: ld returned 1 exit status
make: *** [sapi/cli/php] Error 1

PHP :: Bug #54736 :: Patchesより、パッチが公開されているので適用する

# cd /usr/local/src/php
# curl -sSL "https://bugs.php.net/patch-display.php?bug_id=54736&patch=debian_patches_disable_SSLv2_for_openssl_1_0_0.patch&revision=1305414559&download=1" -o debian_patches_disable_SSLv2_for_openssl_1_0_0.patch
# patch -p1 -b < debian_patches_disable_SSLv2_for_openssl_1_0_0.patch
patching file ext/openssl/xp_ssl.c
Hunk #1 succeeded at 332 (offset 4 lines).
Hunk #2 succeeded at 354 (offset 4 lines).
Hunk #3 succeeded at 583 (offset -50 lines).
Hunk #4 succeeded at 819 (offset -98 lines).

Apache 実行時の PHP5 モジュールエラー

Cannot load modules/libphp5.so into server: /usr/local/apache2/modules/libphp5.so: undefined symbol: unixd_config

# /usr/local/apache2/bin/httpd -DFOREGROUND
httpd: Syntax error on line 157 of /usr/local/apache2/conf/httpd.conf: Cannot load modules/libphp5.so into server: /usr/local/apache2/modules/libphp5.so: undefined symbol: unixd_config

CentOS7.1 に PHP5.2.17 環境を構築する – Qiitaphp5.2.14 と apache2.4.3 – rougeref’s diaryより、Apache 2.4 では unix_configap_unixd_config に変更された

ap_unixd_config に合わせるように sapi/apache2handler/php_functions.c 内を変更する。変更箇所は上記リンク参照

変更箇所はパッチ形式になっているので、パッチファイル名を libphp5.so.patch として作成・保存し、適用する

# patch -l -p0 -b < libphp5.so.patch
patching file sapi/apache2handler/php_functions.c

その他のエラー

buildconf: Your version of autoconf likely contains buggy cache code.

当初、php/Dockerfile at 0985a4d4ba7d16e273d14ca582562767b823cf08 · docker-library/phpをベースしていたころ、 ./buildconf --forceの実行時に発生したエラー

./buildconf --force
Forcing buildconf
buildconf: checking installation...
buildconf: autoconf version 2.69 (ok)
buildconf: Your version of autoconf likely contains buggy cache code.
           Running vcsclean for you.
           To avoid this, install autoconf-2.13.
Can't figure out your VCS, not cleaning.

编译 php 报 Can’t figure out your VCS, not cleaning – 夜空より、

autoconf2.13 をインストールする

apt-get install -y autoconf2.13

再度実行

./buildconf --force
Forcing buildconf
buildconf: checking installation...
buildconf: autoconf version 2.13 (ok)

patch コマンドの-l オプション

上記 libphp5.so.patch をサイトのコードをコピーして保存し、patch コマンドで適用しようとしたところ、内容は問題ないのに正常に適用できなかった。

# patch -p0 -b < libphp5.so.patch
patching file sapi/apache2handler/php_functions.c
Hunk #1 FAILED at 383.
Hunk #2 FAILED at 414.
2 out of 2 hunks FAILED -- saving rejects to file sapi/apache2handler/php_functions.c.rej

元のソースコードとパッチの差分をよく確認してみると、ソースコードはタブ、パッチファイルはスペースになっていた。

コードの内容は問題なかったので、-l オプションをつけて空白とタブの区別を無視したうえでパッチを適用するようにした

# patch -l -p0 -b < libphp5.so.patch
patching file sapi/apache2handler/php_functions.c

参考

Vaultwardenを使う

Vaultwarden (旧:Bitwarden_RS) はBitwardenサーバの代替実装です。

Rustで書かれており、Bitwardenより軽量です。

APIに互換性があるためBitwardenのクライアントがそのまま利用できます。

条件

  • Docker, Docker Composeはインストール、稼働済み
  • イメージの起動はdocker-composeを使用する
  • WEBアクセスはnginxでプロキシする
  • データベースはホストで稼働中のMySQLを使用する
  • Vaultwardenの管理画面へのアクセスは特定のIPからのみとする

準備

  1. 公開用URL

    https://vaultwarden.example.jp

  2. Vaultwardenからのお知らせをメールで送る際のメールアカウント (SMTPサーバ名、ポート番号、ユーザー名、パスワードなど)

    項目
    メールアドレス(送信元) vaultwarden@example.jp
    SMTPホスト名 smtp.example.jp
    SMTPポート番号 587
    ユーザー名 vaultwarden@example.jp
    パスワード vaultwarden_smtppass
  3. MySQLデータベースにVaultwarden用のデータベースとアクセスユーザー

    項目
    データベース名 vaultwarden
    データベース文字コード utf8mb4
    ユーザー vaultwarden
    パスワード vaultwarden_dbpass
  4. vaultwarden管理画面にログインするためのトークンを生成

    $ openssl rand -base64 48
    xn8/uHwgf7Lp/9VIltS20Buj/NjZCn+7YCbXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

手順

  1. Vaultwarden用のディレクトリを作成

    sudo mkdir /opt/vaultwarden
    cd /opt/vaultwarden
    
  2. docker-compose.ymlの作成

    linux環境では、host.docker.internalが利用できないので、linuxでhost.docker.internalを使う – Qiitaより、extra_hostsで定義しておく

    version: '3'
    
    services:
      vaultwarden:
        image: vaultwarden/server:alpine
        env_file:
          - ./vaultwarden.env
        volumes:
          - ./vaultwarden:/data
        ports:
          - "127.0.0.1:10080:80"
          - "127.0.0.1:13012:3012"
        extra_hosts:
          - "host.docker.internal:host-gateway"
    
  3. 永続データ保存用ディレクトリ作成

    $ mkdir vaultwarden
    
  4. 設定ファイルのテンプレートをダウンロードしてvaultwarden.envとして保存

    $ curl -L -o vaultwarden.env https://raw.githubusercontent.com/dani-garcia/vaultwarden/main/.env.template
    
  5. vaultwarden.envを編集して、各項目を設定

    • メール
    • データベース
    • 管理画面用アクセストークン
    • WEBソケット有効化
    • クライアント側からのユーザー新規作成・招待の禁止
    @@ -17,7 +17,7 @@
     # DATABASE_URL=data/db.sqlite3
     ## When using MySQL, specify an appropriate connection URI.
     ## Details: https://docs.diesel.rs/diesel/mysql/struct.MysqlConnection.html
    -# DATABASE_URL=mysql://user:password@host[:port]/database_name
    +DATABASE_URL=mysql://vaultwarden:vaultwarden_dbpass@host.docker.internal/vaultwarden
     ## When using PostgreSQL, specify an appropriate connection URI (recommended)
     ## or keyword/value connection string.
     ## Details:
    @@ -55,7 +55,7 @@
     # WEB_VAULT_ENABLED=true
    
     ## Enables websocket notifications
    -# WEBSOCKET_ENABLED=false
    +WEBSOCKET_ENABLED=true
    
     ## Controls the WebSocket server address and port
     # WEBSOCKET_ADDRESS=0.0.0.0
    @@ -195,7 +195,7 @@
     # EMAIL_TOKEN_SIZE=6
    
     ## Controls if new users can register
    -# SIGNUPS_ALLOWED=true
    +SIGNUPS_ALLOWED=false
    
     ## Controls if new users need to verify their email address upon registration
     ## Note that setting this option to true prevents logins until the email address has been verified!
    @@ -226,14 +226,14 @@
     ## Token for the admin interface, preferably use a long random string
     ## One option is to use 'openssl rand -base64 48'
     ## If not set, the admin panel is disabled
    -# ADMIN_TOKEN=Vy2VyYTTsKPv8W5aEOWUbB/Bt3DEKePbHmI4m9VcemUMS2rEviDowNAFqYi1xjmp
    +ADMIN_TOKEN=xn8/uHwgf7Lp/9VIltS20Buj/NjZCn+7YCbXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
     ## Enable this to bypass the admin panel security. This option is only
     ## meant to be used with the use of a separate auth layer in front
     # DISABLE_ADMIN_TOKEN=false
    
     ## Invitations org admins to invite users, even when signups are disabled
    -# INVITATIONS_ALLOWED=true
    +INVITATIONS_ALLOWED=false
     ## Name shown in the invitation emails that don't come from a specific organization
     # INVITATION_ORG_NAME=Vaultwarden
    
    @@ -272,7 +272,7 @@
     ## It's recommended to configure this value, otherwise certain functionality might not work,
     ## like attachment downloads, email links and U2F.
     ## For U2F to work, the server must use HTTPS, you can use Let's Encrypt for free certs
    -# DOMAIN=https://bw.domain.tld:8443
    +DOMAIN=https://vaultwarden.example.jp
    
     ## Allowed iframe ancestors (Know the risks!)
     ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors
    @@ -333,13 +333,13 @@
     ## Mail specific settings, set SMTP_HOST and SMTP_FROM to enable the mail service.
     ## To make sure the email links are pointing to the correct host, set the DOMAIN variable.
     ## Note: if SMTP_USERNAME is specified, SMTP_PASSWORD is mandatory
    -# SMTP_HOST=smtp.domain.tld
    -# SMTP_FROM=vaultwarden@domain.tld
    +SMTP_HOST=smtp.example.jp
    +SMTP_FROM=vaultwarden@example.jp
     # SMTP_FROM_NAME=Vaultwarden
     # SMTP_SECURITY=starttls # ("starttls", "force_tls", "off") Enable a secure connection. Default is "starttls" (Explicit - ports 587 or 25), "force_tls" (Implicit - port 465) or "off", no encryption (port 25)
    -# SMTP_PORT=587          # Ports 587 (submission) and 25 (smtp) are standard without encryption and with encryption via STARTTLS (Explicit TLS). Port 465 is outdated and used with Implicit TLS.
    -# SMTP_USERNAME=username
    -# SMTP_PASSWORD=password
    +SMTP_PORT=465        # Ports 587 (submission) and 25 (smtp) are standard without encryption and with encryption via STARTTLS (Explicit TLS). Port 465 is outdated and used with Implicit TLS.
    +SMTP_USERNAME=vaultwarden@example.jp
    +SMTP_PASSWORD=vaultwarden_smtppass
     # SMTP_TIMEOUT=15
    
     ## Defaults for SSL is "Plain" and "Login" and nothing for Non-SSL connections.
    
    

    その他、必要に応じてコメントアウトを外して設定

  6. NGINXにプロキシ設定を追加

    Proxy examples · dani-garcia/vaultwarden Wikiを参考にnginxにプロキシ設定を追加する certbotでLet’s EncryptのSSLを追加する

    server {
        server_name vaultwarden.example.jp;
    
        location / {
            proxy_pass http://localhost:10080;
            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;
        }
    
        access_log  /var/log/nginx/vaultwarden-access.log  main;
        error_log  /var/log/nginx/vaultwarden-error.log warn;
    
        listen 443 ssl http2; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/vaultwarden.example.jp/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/vaultwarden.example.jp/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
        # https://github.com/dani-garcia/vaultwarden/wiki/Proxy-examples
        client_max_body_size 128M;
    
        location /notifications/hub {
            proxy_pass http://localhost:13012;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    
        location /notifications/hub/negotiate {
            proxy_pass http://localhost:10080;
        }
    
        # Optionally add extra authentication besides the ADMIN_TOKEN
        # If you don't want this, leave this part out
        location /admin {
            # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/
            # auth_basic "Private";
            # auth_basic_user_file /path/to/htpasswd_file;
            allow XXX.XXX.XXX.XXX;
            deny all;
    
            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_pass http://localhost:10080;
        }
    }
    
    server {
        if ($host = vaultwarden.example.jp) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        listen 80;
        server_name vaultwarden.example.jp;
        return 404; # managed by Certbot
    }
    
  7. 最終ファイル構成

    /opt/vaultwarden
    |--docker-compose.yml
    |--vaultwarden.env
    |--vaultwarden/
    
  8. Dockerコンテナを起動

    $ docker-compose up -d
    

確認

  1. データベース内にテーブルが作成されているか

  2. URLでアクセスできるか

    https://vaultwarden.example.jp/ image-1790_1

  3. 管理画面(/admin)へのアクセスとADMIN_TOKENを使ってログインできるか

    https://vaultwarden.example.jp/admin/ image-1790_2

    image-1790_3

  4. メールが送信できるか

    SMTP Email Settings タブを開いて、Test SMTP の欄に送り先のメールアドレスを入力して、Send test email ボタンを押下

    image-1790_4 テストメールが届いているか

    image-1790_5

ユーザ登録

設定ファイルでユーザーが新規に登録するのを禁じたので、管理画面から登録する

  1. 管理画面の上部メニューUsersを選択

  2. Invite UserにアカウントIDとなるメールアドレスを入力してInviteボタン押下して招待メールを送信

    image-1790_6

  3. 招待メールの中にあるJoin Organization Nowリンクをクリック

    image-1790_7

    Create Accountボタンを押下

    image-1790_8

  4. 表示名、マスターパスワード、マスターパスワードヒントを設定してユーザー登録を完了させる

    image-1790_9

クライアントから利用する

Bitwardenのクライアントからクライアントをダウンロード、インストール

Chromeの場合

  1. 拡張機能導入直後

    image-1790_10

  2. 左上の歯車をクリックして設定を開き、サーバURLに*VaultwardenのURLを入力し、それ以外の項目は空白のままで保存をクリック

    image-1790_11

  3. ログインから作成したユーザーのメールアドレスとマスターパスワードでログインする

その他

SQLiteからMySQLへ移行

Vaultwardenのデフォルトデータベース(設定ファイルでDATABASE_URLを設定していない場合)はSQLiteのため、MySQLを利用するときはデータを移行することで引継ぎができる

Using the MariaDB (MySQL) Backend · dani-garcia/vaultwarden Wiki · GitHub

  1. VaultwardenのDockerイメージを更新し、最新イメージで起動する (SQLiteデータベースが最新にマイグレーションされる)

  2. DATABASE_URLでMySQLを利用するように設定して、Vaultwardenを起動する (MySQLデータベース上にテーブルが作成される)

  3. 上記Wikiを参考に、SQLiteからMySQL用のINSERT分のSQLを生成する

    1. sqlite3コマンドでINSERT文だけダンプする

      cd /opt/vaultwarden/vaultwarden
      sudo sqlite3 db.sqlite3 .dump | grep "^INSERT INTO" | grep -v "__diesel_schema_migrations" > sqlitedump.sql
      echo "SET FOREIGN_KEY_CHECKS=0;" > mysqldump.sql
      cat sqlitedump.sql >> mysqldump.sql
      
    2. このままだとINSERT INTO "テーブル名" VALUES (......)の形式になっており、MySQLのインポートでSyntaxエラーになるためテーブル名を囲っているクォーテーションを取り除く

      sed -i.bak -E 's/^INSERT INTO "(\w+)" VALUES/INSERT INTO \1 VALUES /g' mysqldump.sql
      
    3. MySQLへインポートさせる

      mysql --default-character-set=utf8 vaultwarden < mysqldump.sql
      

phpMyAdmin の Docker 版 FPM イメージを使う2

Nextcloud の Docker FPM バージョンの使い方に、volumes_from を使用して httpd と nextcloud のディレクトリを共有する使い方があったので、試してみる

バージョン 3 の docker-compose.yml で volumes_from を使う – Qiitaより、volumes_from は version 2 系の仕様のため、version 3 系で使用するには、最上位の volumes キーでボリュームを定義し、各サービスの volumes キーでそれを利用する形にする

サンプル

  • docker-compose.yml

    version: "3"
    
    services:
      db:
        image: mysql:8
        environment:
          MYSQL_ROOT_PASSWORD: pass
          MYSQL_DATABASE: my_db
          MYSQL_USER: my_user
          MYSQL_PASSWORD: my_pass
    
      web:
        build: web
        ports:
          - "80:80"
        volumes:
          - ./web/phpmyadmin.conf:/usr/local/apache2/conf/phpmyadmin.conf:ro
          - data:/usr/local/apache2/htdocs
        depends_on:
          - phpmyadmin
    
      phpmyadmin:
        image: phpmyadmin:fpm-alpine
        environment:
          PMA_HOST: db
        volumes:
          - data:/var/www/html
        depends_on:
          - db
    
    volumes:
      data:
    
  • web/Dockerfile

    FROM httpd:2-alpine
    RUN sed -i \
        -e 's/^#\(LoadModule .*proxy_module\)/\1/' \
        -e 's/^#\(LoadModule .*proxy_fcgi_module\)/\1/' \
        conf/httpd.conf
    RUN echo 'Include conf/phpmyadmin.conf' >> /usr/local/apache2/conf/httpd.conf
    
    
  • web/phpmyadmin.conf

    DirectoryIndex index.php
    
    ProxyPassReverse ^/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    ProxyPassMatch ^/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    
    

ポイント

  • 最上位でボリュームdataを定義し、phpmyadmin コンテナの*/var/www/htmlと web コンテナ(Apache)の/usr/local/apache2/htdocs*にマウントする
  • web コンテナは PHPMyAdmin へのプロキシ設定を追加するため、httpdイメージを元にカスタマイズする、前回はオリジナルの httpd.conf を元に変更した httpd.conf を追加していたが、今回は設定ファイルを分けて読み込む形にした
  • depends_onを使用して、web コンテナの起動は phpmyadmin コンテナの後にする、逆の順番(phpmyadmin → web)で起動すると、
    1. phpmyadmin コンテナの初回起動によって、/var/www/html 以下に PHPMyAdmin が展開される
    2. web コンテナの初回起動時によって/usr/local/apache2/に Apache が展開される。(/usr/local/apache2/htdocs に index.html が置かれる)
    3. 両方ともボリュームで共有されているため、後で起動したほう(httpd)で上書きされてしまう
    4. 結果アクセスすると index.html しかない状況になる

docker-compose upで db コンテナの起動の完了を待って http://localhost でアクセスすると PHPMyAdmin が表示される。

このとき、PHP ファイルは phpmyadmin コンテナ上の PHP-FPM で処理され、CSS や Javascript,画像類は web コンテナ上の Apache からレスポンスされるため、前回のようにContent-typeを再定義する必要なない

phpmyadmin_1  | 172.24.0.Z -  DD/MMM/YYYY:HH:II:SS +0000 "GET /index.php" 200
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET / HTTP/1.1" 200 5007
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /themes/pmahomme/jquery/jquery-ui.css HTTP/1.1" 200 36566
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /js/vendor/codemirror/addon/lint/lint.css?v=5.1.3 HTTP/1.1" 200 3035
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /js/vendor/jquery/jquery.min.js?v=5.1.3 HTTP/1.1" 200 89501
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /js/vendor/codemirror/addon/hint/show-hint.css?v=5.1.3 HTTP/1.1" 200 623
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /js/vendor/codemirror/lib/codemirror.css?v=5.1.3 HTTP/1.1" 200 8709
web_1       | 172.24.0.X - - [DD/MMM/YYYY:HH:II:SS +0000] "GET /js/vendor/jquery/jquery-migrate.js?v=5.1.3 HTTP/1.1" 200 25300
:
:
:

image-20220414133025779

サブディレクトリのサンプル

http://localhost/phpMyAdmin のようにサブディレクトリで運用したいときは、httpd の volumes のマウント先と、プロキシの設定を URL のパスに合わせて変更するだけ

  • docker-compose.yml

           - "80:80"
         volumes:
           - ./httpd/phpmyadmin.conf:/usr/local/apache2/conf/phpmyadmin.conf:ro
    -      - data:/usr/local/apache2/htdocs
    +      - data:/usr/local/apache2/htdocs/phpMyAdmin
         depends_on:
           - phpmyadmin
    
  • web/phpmyadmin.conf

     DirectoryIndex index.php
    
    -ProxyPassReverse ^/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    -ProxyPassMatch ^/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    +ProxyPassReverse ^/phpMyAdmin/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    +ProxyPassMatch ^/phpMyAdmin/(.*\.php) fcgi://phpmyadmin:9000/var/www/html/$1
    

ホスト側 Apache とつなげようとしたができなかった

ホスト上にある、MySQL と Apache に接続したくて、volumes を使って、PHPMyAdmin のコードをホスト上に展開させ、それ Apache から参照させつつ、PHP に関しては phpmyadmin コンテナに流す設定にしたかったが、./data に PHPMyAdmin のコードが展開されないためできなかった

docker-compose.yml

phpmyadmin:
  image: phpmyadmin:fpm-alpine
  environment:
    - PMA_HOST=host.docker.internal
  ports:
    - 9000:9000
  volumes:
    - ./data:/var/www/html
  extra_hosts:
    - "host.docker.internal:host-gateway"

Support request: How do you use the FPM version? · Issue #284 · phpmyadmin/docker · GitHubより、コンテナ構築時に/var/www/html に展開しているため、その後コンテナ開始時に volumes によりマウントするため中身がなくなってしまうための模様