

pythonにはBlockextというScratch2.0上に拡張ブロックを生成できるS2eファイルを生成するモジュールがあります。そしてそのs2eファイルをダウンロードできるローカルサーバを立ち上げることが出来ます。以下がそのソースコードです。

[test.py]

[code]

    from blockext import run, reporter, command
    message = ""
    @command("set message %s")
    def set_message(m):
        global message
        message = m
    @reporter("get message")
    def get_message():
        return message
    if __name__ == "__main__":
        run("Ex Test", "ex_test", 5678)
    
[/code]

私はこのpythonプログラムをdockerでコンテナ化し、複数人がこの拡張ブロックをコンテナを通じて使えるようにしたいです。  
しかし、コンテナのサーバに繋げられそうなのですがPythonプログラムのサーバに繋げることが出来ません。コンテナ内ではPythonプログラムはしっかり動いています。下の図のようになっています。

[![画像の説明をここに入力](https://i.stack.imgur.com/bj3dx.jpg)](https://i.stack.imgur.com/bj3dx.jpg)

どうすればブラウザとpythonプログラムのサーバを繋げることが出来るでしょうか？  
アドバイスをいただきたいです。

**Dockerfile**

[code]

    FROM python:3.7.3
    COPY test.py /app/
    WORKDIR /app
    RUN apt-get update
    RUN apt-get install -y vim
    RUN apt-get install -y curl
    EXPOSE 80
    CMD ["python", "test.py"]
    
[/code]


CC BY-SA 4.0
2020-02-03T10:49:23.923
62746
2022-06-06T02:01:00.090
2020-02-04T05:24:30.287
37702
37702
question
python docker
Dockerでwebサーバを立ち上げるpythonプログラムをコンテナ化したい


プログラムが待ち受けているポートが5678ですから、Dockerコンテナを動かす時に通信で使うコンテナ内ポートも5678にする必要があります。

8080:5678でつながるかどうか確かめてみてください。


CC BY-SA 4.0
2020-02-04T05:32:54.447
62759
2020-02-04T05:32:54.447
21329
62746
answer


## 前提知識

HTTP通信を含むソケット通信では、

  * 待ち受けするポート番号
  * 待ち受けするIPアドレス

の情報が必要です。ここでポート番号は現状のマシンで使われていない任意の番号を使用することができます。  
次のIPアドレスについて、これはそのマシンが持っているどのネットワークインターフェースからの通信に対して許可するかを設定するものです。大抵のマシンは2つのネットワークインターフェースを持っています。

  * `lo`。localhostとかループバックアドレス等と呼ばれている`127.0.0.1`のことです。
  * `eth0`。他のコンピュータと接続している側のネットワークインターフェースです。普通にLANポートと思っておけば良いと思います。こちら側のインターフェースは、大抵`172.17.x.x`といったクラスBのプライベートネットワークアドレスです。

dockerのコンテナは通常この2つのネットワークインターフェースを持っていると考えて構いません。`lo`は特に説明不要だと思います。`eth0`はコンテナの外と通信するためのインターフェースです。

ソケットを作成し外から通信できるようにする（bindとかlistenする等と呼びます）ためにはどのネットワークインターフェースからの通信を許可するかをその際に決めなければなりません。どれか1つから待ち受けするのも可能ですし、全ネットワークインターフェースから待ち受けすることも可能です。その場合、待ち受けIPアドレスとして`0.0.0.0`を指定します。

## 質問の問題の本質

待ち受けアドレスを`localhost`で指定すると、そのコンピュータ自身からの通信しか受け付けなくなります。コンテナも同様で、コンテナ自身からの通信しか受け付けません。  
コンテナの外から通信を受け付けたい場合は、多くの場合`0.0.0.0`を指定して待ち受けします。この設定と、`docker
run`する際の`-p`オプションでコンテナのポート番号とホストのポート番号を紐づけることでコンテナとホスト側との通信が可能になっています。これはdockerの基本ですね。

さて、このプログラムで使用している blockext は、`run`メソッドでWebサーバを指定のポートで立ち上げますが、待ち受けIPアドレスは
`localhost`
でハードコーディングされています。したがってコンテナ自身以外からの通信しか受け付けません。モジュール利用側からIPアドレスを設定する方法も用意されていないようです。  
なので、モジュールを改変しない限り docker を使って blockext を動かすことは残念ながら **不可能** です。

## さらに悲しいことに

[blockext の Github リポジトリ](https://github.com/blockext/blockext)を見ると、このモジュールは
DEPRECATED と書かれています。つまり開発は放棄され、もう使用しないでほしい、とのことです。

残念であるとは思いますが、他の方法を模索したほうが生産的だと思われます。  
もしくはリポジトリをforkして、ご自身で開発を引き継ぐか、でしょうか。


CC BY-SA 4.0
2021-06-27T15:45:48.210
77821
2021-06-27T22:54:02.970
2021-06-27T22:54:02.970
35558
46944
62746
answer