Dockerをreadonlyで動かす

概要

セキュリティ向上のためにdockerをreadonlyで動かすためのメモ

まずは動かす

そのままやっても動かない。

$ docker run --rm --read-only nginx:latest
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f3ac85625e76: Already exists
2f2ae0d10f0c: Pull complete
686758060351: Pull complete
9d6463e85319: Pull complete
bb6dfee87e07: Pull complete
594d75b0add1: Pull complete
Digest: sha256:3b89317d99358692e82aa34d38c52085a937e437daaaf05aa17522460883452e
Status: Downloaded newer image for nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/12/06 05:49:38 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)

エラーになった所をマウントしたら動いた。

$ docker run --rm --read-only -v /var/cache/nginx -v /var/run/ -p 80:80 nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/12/06 05:54:05 [notice] 1#1: using the "epoll" event method
2022/12/06 05:54:05 [notice] 1#1: nginx/1.23.2
2022/12/06 05:54:05 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/12/06 05:54:05 [notice] 1#1: OS: Linux 5.10.124-linuxkit
2022/12/06 05:54:05 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/12/06 05:54:05 [notice] 1#1: start worker processes
2022/12/06 05:54:05 [notice] 1#1: start worker process 21
2022/12/06 05:54:05 [notice] 1#1: start worker process 22
2022/12/06 05:54:05 [notice] 1#1: start worker process 23
2022/12/06 05:54:05 [notice] 1#1: start worker process 24
172.17.0.1 - - [06/Dec/2022:05:54:09 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [06/Dec/2022:05:54:09 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" "-"
2022/12/06 05:54:09 [error] 22#22: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"

php-fpm

$ cat src/index.php
<?php
print('Hello php-fpm');
?>

srcの直下にindex.phpを設置。

.
└── src
    └── index.php

M1 Macだった場合は --platform linux/amd64 を指定する。Intel版なら不要。

$ docker run --rm --read-only -p 9000:9000 --platform linux/amd64 -v ${PWD}/src/:/var/www/html php:8-fpm

検証する際、php-fpmはHTTPサーバーの機能が無いため、brewでfcgiをインストールして下記を実行する。

$ SCRIPT_FILENAME=index.php REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
X-Powered-By: PHP/8.1.13
Content-type: text/html; charset=UTF-8

Hello php-fpm