August 27, 2023

CentOS 7でPython 3.10と3.11を使う 番外編:Docker

CentOS 7.9にPython 3.10と3.11をソースからインストールしたり、rpm作ってインストールできたので、ここ↓を参考にDockerのPython 3.10と3.11をaliasに設定してCentOS 7にインストールしたかのように使ってみた。
How to dockerize Python environments | by Franz Diebold | Medium

用意したもの

前回と同じくCentOS 7.9を最小構成でセットアップしたVM

$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

手順

Dockerインストール

公式の Install Docker Engine on CentOS | Docker Docs に従う。

  1. リポジトリ追加
    $ sudo yum install -y yum-utils
    $ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
  2. Docker Engineインストール
    $ sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
    
  3. Docker起動と自動起動設定
    $ sudo systemctl enable docker --now
    
  4. dockerグループに追加
    一般ユーザーを使っているはずなので、自分のユーザーをdockerグループに追加する
    $ sudo usermod -aG docker ${USER}
    
  5. グループ追加を反映するためにログアウトして再ログイン
  6. docker動作確認
    こんな風にpermission deniedにならず、
    $ docker version
    Client: Docker Engine - Community
     Version:           24.0.5
     API version:       1.43
     Go version:        go1.20.6
     Git commit:        ced0996
     Built:             Fri Jul 21 20:39:02 2023
     OS/Arch:           linux/amd64
     Context:           default
    permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
    

    Serverバージョンが表示されれば良し

    $ docker version
    Client: Docker Engine - Community
     Version:           24.0.5
     API version:       1.43
     Go version:        go1.20.6
     Git commit:        ced0996
     Built:             Fri Jul 21 20:39:02 2023
     OS/Arch:           linux/amd64
     Context:           default
       
    Server: Docker Engine - Community
     Engine:
      Version:          24.0.5
      API version:      1.43 (minimum version 1.12)
      Go version:       go1.20.6
      Git commit:       a61e2b4
      Built:            Fri Jul 21 20:38:05 2023
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.6.22
      GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
     runc:
      Version:          1.1.8
      GitCommit:        v1.1.8-0-g82f18fe
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
    

使ってみる

DockerイメージはDebianのSlimにした。
Alpineの方が軽量だけど、

$ docker images
REPOSITORY   TAG             IMAGE ID       CREATED        SIZE
python       3.10-slim       1488b8d1803e   34 hours ago   128MB
python       3.11-slim       d64578606786   34 hours ago   130MB
python       3.11-bookworm   28d8ca9ad96d   2 days ago     1.01GB
python       3.10-alpine     532546851701   2 days ago     49.7MB
python       3.10-bookworm   8c24eef72f16   2 days ago     1GB
python       3.11-alpine     9a2ccd0e4ef5   2 months ago   52MB

コンテナ内のOpenSSLが、DebianはLTSで2026/09/07までサポートされる3.0系、Alpineは新しいけど2025/03/14までの3.1系だった。

$ docker run --rm -it python:3.10-slim python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 3.0.9 30 May 2023
$ docker run --rm -it python:3.11-slim python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 3.0.9 30 May 2023
$ docker run --rm -it python:3.10-alpine python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 3.1.2 1 Aug 2023
$ docker run --rm -it python:3.11-alpine python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 3.1.1 30 May 2023

詳細は参考元にお任せするとして、設定するのは以下。

alias python3.10='docker run --rm -it -v "${PWD}":/usr/src/app -v py310_lib:/usr/local/lib -w /usr/src/app python:3.10-slim python'
alias python3.11='docker run --rm -it -v "${PWD}":/usr/src/app -v py311_lib:/usr/local/lib -w /usr/src/app python:3.11-slim python'

次回ログイン時に毎回上記を打ちたくないなら~/.bashrc# User specific aliases and functions行の下に書いておく。
全ユーザーで使えるようにしたければ/etc/profile.d/python.shか何か任意の名前でファイルを作って書いておく。

動作確認

CentOS 7のopensslは1.0系だけど…

$ rpm -qa | grep openssl
openssl-libs-1.0.2k-26.el7_9.x86_64
openssl-1.0.2k-26.el7_9.x86_64
$ openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017
$ python2.7 -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.2k-fips  26 Jan 2017

-v "${PWD}":/usr/src/app によって、Dockerコンテナの外であるカレントディレクトリのスクリプトを実行できるし、OpenSSLはコンテナの中のものを使ってくれる。

$ cat ./ssl-ver.py
import sys,ssl

print(sys.version)
print(ssl.OPENSSL_VERSION)
$ python3.10 ./ssl-ver.py
3.10.13 (main, Aug 26 2023, 00:54:12) [GCC 12.2.0]
OpenSSL 3.0.9 30 May 2023
$ python3.11 ./ssl-ver.py
3.11.5 (main, Aug 25 2023, 23:57:27) [GCC 12.2.0]
OpenSSL 3.0.9 30 May 2023

他のディレクトリはマウントしていないから、カレントディレクトリではないパスのスクリプトは実行できない。

$ cp ./ssl-ver.py /tmp
$ cd /tmp
$ python3.11 ./ssl-ver.py
3.11.5 (main, Aug 25 2023, 23:57:27) [GCC 12.2.0]
OpenSSL 3.0.9 30 May 2023
$ python3.11 /tmp/ssl-ver.py
python: can't open file '/tmp/ssl-ver.py': [Errno 2] No such file or directory

aliasだからshbangで指定はできないけど、

$ ls -l ./ssl-ver.py
-rwxrwxr-x. 1 nissy nissy 62  8月 27 18:56 ./ssl-ver.py
$ cat ./ssl-ver.py
#!/usr/bin/env python3.11

import sys,ssl

print(sys.version)
print(ssl.OPENSSL_VERSION)
$ python3.11 ./ssl-ver.py
3.11.5 (main, Aug 25 2023, 23:57:27) [GCC 12.2.0]
OpenSSL 3.0.9 30 May 2023
$ ./ssl-ver.py
/usr/bin/env: python3.11: そのようなファイルやディレクトリはありません

aliasの代わりにシェルスクリプトにすればshbangは使える。

$ ls -l /usr/local/bin/
合計 8
lrwxrwxrwx. 1 root root  10  8月 27 18:53 python3 -> python3.10
-rwxr-xr-x. 1 root root 129  8月 27 18:45 python3.10
-rwxr-xr-x. 1 root root 129  8月 27 18:40 python3.11
$ cat /usr/local/bin/python3.10
#!/bin/bash

docker run --rm -it -v "${PWD}":/usr/src/app -v py310_lib:/usr/local/lib -w /usr/src/app python:3.10-slim python $@
$ cat /usr/local/bin/python3.11
#!/bin/bash

docker run --rm -it -v "${PWD}":/usr/src/app -v py311_lib:/usr/local/lib -w /usr/src/app python:3.11-slim python $@
$ cat ssl-ver.py
#!/usr/bin/env python3

import sys,ssl

print(sys.version)
print(ssl.OPENSSL_VERSION)
$ ./ssl-ver.py
3.10.13 (main, Aug 26 2023, 00:54:12) [GCC 12.2.0]
OpenSSL 3.0.9 30 May 2023

2024/06/30にEoLを迎えるCentOS 7から別のOSに移行するのが多分正解だけど、暫定策としてお試しで使ってみる分には良いかもしれない。

© 2020 nissy-lab.com