(Ubuntu)Python3.9.1とpyenvをインストールする(Vagrant)

VagrantのUbuntu20.04上にpyenvとPythonの最新バージョンをインストールしていきます。Ubunutu上に「pyenv + Python」の環境を構築をしたい方は、参考にしてください。

目的と動作環境

最終更新日:2021/5/4

VagrantでUbuntu20.04の仮想マシンを作成・起動して、そこでpyenvとPythonの最新バージョン3.9.1(2021/1/20時点)をインストールしていきます。

また、Ubuntu18.04については、仮想マシンの作成・起動だけ書いています。pyenv + Python3.9.1の環境構築は、Ubuntu20.04上でやっていますが、Ubuntu18.04でも同じ手順でできます。

macPC上でのpyenvとPythonの環境構築については別ページで説明していますので、そちらを参考にしてください。
(macOS)pyenvとPython3.9をインストールする

◾️動作環境とバージョン情報です。
ホストPCのOS:macOS Big Sur(バージョン11.1)
Vagrant 2.2.7
VirtualBox 6.1.16

$ vagrant -v
Vagrant 2.2.7

$ VirtualBox -h
Oracle VM VirtualBox VM Selector v6.1.16

VagrantとVirtualBoxをインストールしてある事が前提で説明していきます。

pyenvとは?

pyenvは、Pythonのシンプルなバージョン管理ツールです。様々なバージョンのPythonをインストールする事ができて、インストールしたバージョンを切り替える事もできます。Pythonで何か作る時に、最新バージョンで試したり、過去のバージョンで試したりする事が可能です。ですので開発プロジェクト単位でバージョンを気軽に変更して開発する事もできます。

Ubuntu 20.04 LTSのBoxをダウンロードして、仮想マシンを作成・起動する

まずはpyenvとPythonをインストールするための仮想マシンを作ります。仮想マシンはVagrantを使って作ります。
VagrantでUbuntu20.04のBoxを取得し、そのBoxからUbuntu20.04の仮想マシンを作成して起動までをやります。
Boxは、BentoのUbuntu20.04(bento/ubuntu-20.04)を使います。

適当なディレクトリ上で、vagrant initコマンドを実行してVagrantfileを作成し、Vagrant環境を初期化します。

$ vagrant init bento/ubuntu-20.04
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

$ ls
Vagrantfile
作成されたVagrantfileを編集します(見やすくするために、コメント文はすべて削除しています)。
$ cat Vagrantfile 
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-20.04"
  config.vm.network "private_network", ip: "192.168.33.10"
end
編集すると言っても、プライベートIPアドレスだけ指定するために、config.vm.network "private_network"の行を有効にしただけです。

準備ができたので、仮想マシンを作成して起動します。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/ubuntu-20.04' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'bento/ubuntu-20.04'
    default: URL: https://vagrantcloud.com/bento/ubuntu-20.04
==> default: Adding box 'bento/ubuntu-20.04' (v202012.23.0) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/bento/boxes/ubuntu-20.04/versions/202012.23.0/providers/virtualbox.box
    default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
==> default: Successfully added box 'bento/ubuntu-20.04' (v202012.23.0) for 'virtualbox'!
==> default: Importing base box 'bento/ubuntu-20.04'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'bento/ubuntu-20.04' version '202012.23.0' is up to date...
==> default: Setting the name of the VM: tmp_default_1611060173318_94104
==> default: Fixed port collision for 22 => 2222. Now on port 2201.
〜
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/hogeuser/MyVagrant/tmp

$ vagrant status
Current machine states:

default                   running (virtualbox)
〜

$ vagrant box list
bento/centos-6.8                  (virtualbox, 2.3.4)
bento/ubuntu-20.04                (virtualbox, 202012.23.0)
centos-7.1                        (virtualbox, 0)
precise32                         (virtualbox, 0)
仮想マシンを作成して起動できました!
あと、Boxの一覧を確認すると、bento/ubuntu-20.04が追加されています。

初めてbento/ubuntu-20.04を使う場合、仮想マシンの作成や起動前にbento/ubuntu-20.04のBoxのダウンロードから始まると思うので、少し時間がかかると思います。

もし先にBoxの追加(ダウンロード)だけしたい場合、vagrant addコマンドを実行してBoxのダウンロードしてから、vagrant initコマンドとvagrant upコマンドを実行しても同じ事ができます。

$ vagrant box add bento/ubuntu-20.04
〜
$ vagrant init bento/ubuntu-20.04
〜
Vagrantfileファイルの編集をする
〜
$ vagrant up
〜

それでは、起動した仮想マシンに接続してみます。

$ vagrant ssh
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-58-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue 19 Jan 2021 12:57:10 PM UTC

  System load:  0.0               Processes:             99
  Usage of /:   2.2% of 61.31GB   Users logged in:       0
  Memory usage: 14%               IPv4 address for eth0: 10.0.2.15
  Swap usage:   0%                IPv4 address for eth1: 192.168.33.10


This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
vagrant@vagrant:~$
接続できました。あとちゃんとWelcome to Ubuntu 20.04.1 LTSと書いてありますね。
IPアドレスも確認しておきます。
vagrant@vagrant:~$ ip a
〜
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 06:00:35:0a:65:5e brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe50::d00:43ff:ds0e:642a/64 scope link 
       valid_lft forever preferred_lft forever
Vagrantfileで指定したIPアドレス(192.168.33.10)になっています。

Ubuntu 18.04 LTSのBoxをダウンロードして、仮想マシンを作成・起動する

今度は、Ubuntu18.04の場合についてです。流れはUbuntu20.04の時と全く同じです。使うBoxが異なるだけです。

Ubuntu18.04のBoxは、hashicorp/bionic64、またはbento/ubuntu-18.04のどちらでも良いと思います。
ここでは、hashicorp/bionic64を使います。

Ubuntu20.04(bento/ubuntu-20.04)の時と流れは同じです。

$ #Vagrantfileを作成し、Vagrant環境を初期化する。
$ vagrant init hashicorp/bionic64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

$ ls
Vagrantfile

$ #Vagrantfileを編集する
$ vim Vagrantfile 
$ cat Vagrantfile 
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
  config.vm.network "private_network", ip: "192.168.33.11"
end

$ #仮想マシンの作成と起動(Boxを初めて使う時はBoxのダウンロードから始まる)
tmp2 $ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/bionic64' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/bionic64'
    default: URL: https://vagrantcloud.com/hashicorp/bionic64
==> default: Adding box 'hashicorp/bionic64' (v1.0.282) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/hashicorp/boxes/bionic64/versions/1.0.282/providers/virtualbox.box
    default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
==> default: Successfully added box 'hashicorp/bionic64' (v1.0.282) for 'virtualbox'!
〜
==> default: Mounting shared folders...
    default: /vagrant => /Users/hogeuser/MyVagrant/tmp2

$ vagrant status
Current machine states:

default                   running (virtualbox)
〜

$ #hashicorp/bionic64がBox一覧に追加された
$ vagrant box list
bento/centos-6.8                  (virtualbox, 2.3.4)
bento/ubuntu-20.04                (virtualbox, 202012.23.0)
centos-7.1                        (virtualbox, 0)
hashicorp/bionic64                (virtualbox, 1.0.282
precise32                         (virtualbox, 0)
Ubuntu18.04のBoxをダウンロードしてBox一覧に追加し、そのBoxから仮想マシンを作成して起動することができました!

起動した仮想マシンに接続してみます。

$ vagrant ssh
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)

〜
0 packages can be updated.
0 updates are security updates.

vagrant@vagrant:~$ ip a
〜
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 06:00:35:0a:65:5e brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.11/24 brd 192.168.33.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe50::d00:43ff:ds0e:642a/64 scope link 
       valid_lft forever preferred_lft forever
接続できました。Welcome to Ubuntu 18.04.3 LTSと書いてありますね。
IPアドレスも、Vagrantfileで指定したIPアドレス(192.168.33.11)になっています。

Ubuntu20.04にpyenv + Python3.9.1環境を構築する(まずはpyenvをインストールする)

pyenv + Python3.9.1の環境構築の流れは、Ubuntu20.04とUbuntu18.04でまったく同じですので、以下はUbuntu20.04上でやった事を説明していきます。

次に、作成した仮想マシン(Ubuntu20.04)上にpyenvをインストールし、pyenv上でPythonの最新版3.9.1(2021年1月20日時点)をインストールしていきます。

その前に、aptパッケージを更新しておきます(apt updateとapt upgrade)。

vagrant@vagrant:~$ sudo apt update
Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease                                   
Get:2 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]                
〜
Reading state information... Done
24 packages can be upgraded. Run 'apt list --upgradable' to see them.

vagrant@vagrant:~$ sudo apt upgrade -y
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following NEW packages will be installed:
  linux-image-5.4.0-62-generic linux-modules-5.4.0-62-generic linux-modules-extra-5.4.0-62-generic
〜
Found linux image: /boot/vmlinuz-5.4.0-58-generic
Found initrd image: /boot/initrd.img-5.4.0-58-generic
done

あとUbuntuには最初からPythonが入っていますので、現状の環境のPythonのバージョンなどを最初に確認しておきます。

vagrant@vagrant:~$ python -V
-bash: python: command not found

vagrant@vagrant:~$ python3 -V
Python 3.8.5

vagrant@vagrant:~$ which python3
/usr/bin/python3

vagrant@vagrant:~$ pip -V
-bash: pip: command not found

vagrant@vagrant:~$ pip3 -V
-bash: pip3: command not found
Python3.8.5が最初から入っていました。わりと新しいですね。

それではまずはpyenvからインストールします。
Ubuntuにpyenvをインストールする方法は、pyenv installerというツールを使う方法とGithubからチェックアウトしてインストールする方法があるようですが、ここではGithubからインストールします。

vagrant@vagrant:~$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
Cloning into '/home/vagrant/.pyenv'...
remote: Enumerating objects: 18547, done.
remote: Total 18547 (delta 0), reused 0 (delta 0), pack-reused 18547
Receiving objects: 100% (18547/18547), 3.72 MiB | 2.25 MiB/s, done.
Resolving deltas: 100% (12601/12601), done.

vagrant@vagrant:~$ ls ~/.pyenv/
bin           COMMANDS.md  CONDUCT.md  libexec  Makefile  pyenv.d    src                  test
CHANGELOG.md  completions  Dockerfile  LICENSE  plugins   README.md  terminal_output.png
これで、$HOME/.pyenvディレクトリにpyenvを配置しました。

次に、環境変数PYENV_ROOTの設定と、環境変数PATHにpyenv関連のディレクトリを追加するためのコマンドを実行します。

vagrant@vagrant:~$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
vagrant@vagrant:~$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
vagrant@vagrant:~$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
~/.bashrcファイルの最後に下のコードが追加されるはずです。
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

このコードを簡単に説明しますと、1行目のexport文は、pyenvのルートディレクトリ(~/.pyenv)を環境変数PYENV_ROOTとして設定しています。
2行目のexport文は、環境変数PATHに"~/.pyenv/bin"を追加しています。このディレクトリにpyenvがあります。

そして、3〜5行目のif構文でPATHに"~/.pyenv/shims"を追加しています。
気になる方は、直接eval "$(pyenv init -)"コマンドをターミナル上で実行すれば、確認できるはずです。

そして、~/.bashrcファイルに追記したコードを反映させるためのコマンドを実行します。

exec "$SHELL"
これで、pyenvコマンドが使えるようになります。
vagrant@vagrant:~$ pyenv --version
pyenv 1.2.22-19-g569992f2
あと、PATHも確認しておきます。
vagrant@vagrant:~$ echo $PATH | sed -e 's/:/\n/g'
/home/vagrant/.pyenv/shims
/home/vagrant/.pyenv/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
最初の2つの"/home/vagrant/.pyenv/shims"と"/home/vagrant/.pyenv/bin"が追加されました。

pyenvのPythonなどが使えるようになったはずなので、現状を確認します。

vagrant@vagrant:~$ pyenv versions
Warning: no Python detected on the system

vagrant@vagrant:~$ pyenv version
system (set by /home/vagrant/.pyenv/version)
まだpyenvでPythonをインストールしていないので、何もないですね。

pyenvでPython3.9.1をインストールする

pyenvがインストールできたので、pyenvを使って最新版のPythonをインストールしていきます。
pyenvでインストールできるPythonのバージョンを確認してみます。

vagrant@vagrant:~$ pyenv install --list 
Available versions:
  2.1.3
  2.2.3
 〜
  3.9.0
  3.9-dev
  3.9.1
  3.10-dev
  activepython-2.7.14
〜
現在(2021/1/20時点)の最新安定版は3.9.1なので、これをインストールします。
vagrant@vagrant:~$ pyenv install 3.9.1
Downloading Python-3.9.1.tar.xz...
-> https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tar.xz
Installing Python-3.9.1...

BUILD FAILED (Ubuntu 20.04 using python-build 1.2.22-19-g569992f2)

Inspect or clean up the working tree at /tmp/python-build.20210119200259.42564
Results logged to /tmp/python-build.20210119200259.42564.log

Last 10 log lines:
checking for python3... python3
checking for --enable-universalsdk... no
checking for --with-universal-archs... no
checking MACHDEP... "linux"
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/python-build.20210119200259.42564/Python-3.9.1':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
vagrant@vagrant:~$ 
BUILD FAILED 、、エラーが出て失敗しました。
調べたらいくつかライブラリが必要らしいので、それをインストールします。
$ sudo apt install -y build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev tk-dev
できました。再度Python3.9.1をインストールします。
vagrant@vagrant:~$ pyenv install 3.9.1
Downloading Python-3.9.1.tar.xz...
-> https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tar.xz
Installing Python-3.9.1...
Installed Python-3.9.1 to /home/vagrant/.pyenv/versions/3.9.1
今度はインストールできました!

pyenvでPythonのバージョンを確認してみます(pyenv versionsコマンドは、pyenvで追加したPythonのバージョン一覧を表示します。pyenv versionコマンドは、現在選択しているPythonのバージョンを表示します)。

vagrant@vagrant:~$ pyenv versions
  3.9.1

vagrant@vagrant:~$ pyenv version
system (set by /home/vagrant/.pyenv/version)
Python3.9.1は追加されましたが、まだ選択されていません。
ですので、pyenv globalコマンドで使用するPythonを切り替えます。
vagrant@vagrant:~$ pyenv global 3.9.1
vagrant@vagrant:~$ pyenv version
3.9.1 (set by /home/vagrant/.pyenv/version)
選択されていいるバージョンが3.9.1になりました!
また、設定を反映させるためのコマンドを実行します(ログインし直しても設定は反映されます)。
vagrant@vagrant:~$ exec "$SHELL"

これでPython3.9.1が使えるようになったはずなので、確認してみます。

vagrant@vagrant:~$ python -V
Python 3.9.1

vagrant@vagrant:~$ python3 -V
Python 3.9.1

vagrant@vagrant:~$ which python
/home/vagrant/.pyenv/shims/python

vagrant@vagrant:~$ which python3
/home/vagrant/.pyenv/shims/python3

vagrant@vagrant:~$ pip -V
pip 20.2.3 from /home/vagrant/.pyenv/versions/3.9.1/lib/python3.9/site-packages/pip (python 3.9)

vagrant@vagrant:~$ which pip
/home/vagrant/.pyenv/shims/pip
ちゃんとPythonのバージョンは3.9.1になっています。また、使われているpython,pipコマンドは、pyenv(~/.pyenv/shims)配下の物になっています。

これでpyenv + pythonの最新版の環境を作るという当初のゴールまでたどり着くことができました!

Pythonをインタラクティブモードで使ってみる。動作確認

せっかくPythonをインストールしたので、インタラクティブモード(対話モード)で少し使ってみます。
インタラクティブモードにはpythonコマンドで入れます。

vagrant@vagrant:~$ python
Python 3.9.1 (default, Jan 19 2021, 20:31:28) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
簡単な計算をしたり、文字列を表示したり、カレンダーを表示してみます。
vagrant@vagrant:~$ python
Python 3.9.1 (default, Jan 19 2021, 20:31:28) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 100  + 100 * 2
300
>>> print("Hello World!!!")
Hello World!!!
>>> import calendar
>>> print(calendar.month(2021, 2))
   February 2021
Mo Tu We Th Fr Sa Su
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28

>>> quit()
vagrant@vagrant:~$ 
インタラクティブモードから抜ける時は、"quit()"と入力するか、ショートカット"Ctrl + D"でできます。

pyenvについてその他色々

pyenvについてその他のメモです。

pyenvでインストールした各pythonがあるディレクトリです。

vagrant@vagrant:~$ ls ~/.pyenv/versions
3.9.1
vagrant@vagrant:~$ #pyenvのルートパス表示
vagrant@vagrant:~$ pyenv root
/home/vagrant/.pyenv

vagrant@vagrant:~$ #pyenvのヘルプ表示
vagrant@vagrant:~$ pyenv --help
Usage: pyenv <command> [<args>]

Some useful pyenv commands are:
   commands    List all available pyenv commands
   exec        Run an executable with the selected Python version
   global      Set or show the global Python version(s)
   help        Display help for a command
   hooks       List hook scripts for a given pyenv command
   init        Configure the shell environment for pyenv
   install     Install a Python version using python-build
   local       Set or show the local application-specific Python version(s)
   prefix      Display prefix for a Python version
   rehash      Rehash pyenv shims (run this after installing executables)
   root        Display the root directory where versions and shims are kept
   shell       Set or show the shell-specific Python version
   shims       List existing pyenv shims
   uninstall   Uninstall a specific Python version
   --version   Display the version of pyenv
   version     Show the current Python version(s) and its origin
   version-file   Detect the file that sets the current pyenv version
   version-name   Show the current Python version
   version-origin   Explain how the current Python version is set
   versions    List all Python versions available to pyenv
   whence      List all Python versions that contain the given executable
   which       Display the full path to an executable

ソースからPythonをインストールする方法について

以上簡単でしたが、Ubuntu20.04上にpyenvとPython3.9.1のインストールについて説明しました。
上で書いた説明ではPythonの3.9.1だけしかインストールしませんでしたが、pyenvを使えば、新しいPythonのバージョンが出た時や過去のバージョンを試したい時に、簡単にインストールして手軽にPythonのバージョンを切り替える事ができるので、テスト環境や試す環境としてとても便利です。

またpyenvを使わずに、ソースから直接PythonをUbuntuにインストールしたい場合は別ページで説明してますので、そちらを参考にしていただければと思います。
(Ubuntu)Python3.9.1をソースからインストールする(Vagrant)

venvでPythonの仮想環境を作る

pyenvを使うことでPythonのバージョンを切り替える事ができるようになりましたが、Pythonのvenvという機能を使えば、Pythonの仮想環境を作成し、仮想環境毎にpipで管理するパッケージを分ける事が可能になります。

venvについては別ページで説明していますので、そちらも参考にしてみてください。
venvでPythonの仮想環境を試してみる

参考サイト

pyenv Github
pyenv Github - Common build problems
->pyenvのトラブルシューティング。OS別でpyenv installでpythonをインストールする前に必要なライブラリについて書いてある(Ubuntu/Debian、Fedora/CentOS/RHEL(aws ec2)、macOS、etc)。
Ubuntu環境のPython
Vagrant Boxes