μλ‘μ΄ 0.15.0μ Windowsμ© Dockerμμ μ€νλμ§ μμ΅λλ€. λ€λ₯Έ νλ«νΌμμ Dockerλ₯Ό μλνμ§ μμμ΅λλ€.
Flaskλ₯Ό μ¬μ©ν μ΅μνμ μ.
μ±.νμ΄
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, world!'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
λ컀νμΌ
FROM python:3-onbuild
COPY . /usr/src/app
CMD ["python", "app.py"]
μꡬ μ¬ν.txt
# Werkzeug==0.14.1
Flask
docker build -t flask_test .
λ₯Ό μ€νν λ€μ docker run flask_test
λ₯Ό μ€νν©λλ€.
컨ν
μ΄λ μ€λ₯:
Ξ» docker run flask_test
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
Traceback (most recent call last):
File "app.py", line 11, in <module>
app.run(debug=True, host='0.0.0.0')
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 943, in run
run_simple(host, port, self, **options)
File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 988, in run_simple
run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
sys.exit(reloader.restart_with_reloader())
File "/usr/local/lib/python3.6/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
exit_code = subprocess.call(args, env=new_environ, close_fds=False)
File "/usr/local/lib/python3.6/subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/local/lib/python3.6/subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "/usr/local/lib/python3.6/subprocess.py", line 1344, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: '/usr/src/app/app.py
requirements.txt
μμ 첫 λ²μ§Έ μ€μ μ£Όμ μ²λ¦¬λ₯Ό μ κ±°νλ©΄ λ€μ λΉλν ν μ λλ‘ μ€νλ©λλ€.
μλ νμΈμ κ°μ λ¬Έμ μ λλ€. ν μ€νΈ λ μ§
μ΄κ²μ _reloading.pyμμ _get_args_for_reloading()
μ λ³κ²½μΌλ‘ μΈν΄ λ°μν©λλ€.
μμ μ½λκ° app.pyλΌλ νμΌμ μκ³ cwd()κ° /home/user/Projects/test/
μΈ κ²½μ°
_get_args_for_reloading()
λ λ€μμ μμ±ν©λλ€.
0.14.1
μ¬μ©:
['/home/user/.virtualenvs/test-ChRUEUMK/bin/python', 'app.py']
0.15.0
μ ν¨κ»
['/home/user/Projects/test/app.py']
κ²½λ‘ μμ /home/user/.virtualenvs/test-ChRUEUMK/bin/python
λ₯Ό μΆκ°νλ©΄ λ¬Έμ κ° ν΄κ²°λ©λλ€.
@shinuza app.pyκ° μ€ν κ°λ₯νμ§ νμΈνκ³ μ€ν κ°λ₯ν κ²½μ° - chmod 644 app.pyλ₯Ό μ€μ ν©λλ€. λλ λ λ²μ§Έ λ°©λ²μΌλ‘ #!/usr/bin/env pythonκ³Ό κ°μ΄ app.py μλ¨μ shebangμ μΆκ°ν©λλ€.
@shinuza κ±°κΈ° https://github.com/pallets/werkzeug/blob/0.15.x/src/werkzeug/_reloader.py#L90 λΌμΈ 90-94 "'/home/user/.virtualenvs/test-ChRUEUMK/bin /python'"μ app.py μ€ν νμΌμΈ κ²½μ° μ κ±°λμμ΅λλ€.
and OSError: [Errno 8] Exec νμ μ€λ₯: '/usr/src/app/app.py app.pyμ shebang μ€μ΄ μκΈ° λλ¬Έμ λ°μνμ΅λλ€(https://stackoverflow.com/questions/27606653/oserror-errno- 8 μ€ν νμ μ€λ₯)
@kamyanskiy λ°©κΈ μ½λλ₯Ό μ½κ³ μ΄κ²μ μμ λμ§λ§ μ€λ₯λ μ§κΈκ³Ό κ°μ΄ λΉλ°μ€λ¬μμΌν©λλ€.
λν λͺ
μμ μΌλ‘ python app.py
λ₯Ό μ€ννλ©΄ νμ νλ‘μΈμ€κ° κ°μ νμ§ μκ³ μμ© νλ‘κ·Έλ¨μ μ€ννλ λ°©μμ λ³κ²½ν΄μλ μ λ©λλ€. μ: 곡μ ν΄λκ° μλ κ°μ λ¨Έμ μΌλ‘ μμ
νλ©΄ κΈ°λ³Έμ μΌλ‘ λͺ¨λ νμΌμ μ€νν μ μμ΅λλ€.
@shinuza λλ κ·Έκ²μ΄ μΉλͺ μ μΈ λ²κ·ΈλΌκ³ μκ°νμ§ μμ΅λλ€. μ¦, μ΄μ λ³΄λ€ μ§κΈμ΄ μ‘°κΈ λ μ격ν©λλ€. λ°λΌμ shebang μμ΄ μ€ν κ°λ₯ν app.pyκ° μμ΄μλ μ λ©λλ€. μλ―Έκ° μμ΅λλ€. κ·Έλ¦¬κ³ λ λ²μ§Έλ‘ "python app.py"μ κ°μ shebangμΌλ‘ μ€ν νμΌμ μ€νν΄μλ μλ©λλ€. κ·Έλ¬λ λλ λμν©λλ€. μλ§λ μ μκ²λ μμμΉ λͺ»ν μΌμ΄μμ΅λλ€. :) ν΄κ²° λ°©λ²μ app.pyμ shebangμ μΆκ°νκΈ°λ§ νλ©΄ λ©λλ€. μ΄κ²μ΄ λμμ΄ λκΈ°λ₯Ό λ°λλλ€.
μ€ν¬λ¦½νΈλ₯Ό μ€ν κ°λ₯ν κ²μΌλ‘ νμνλ κ²½μ° ν΄λΉ μΈν°νλ¦¬ν° μ£Όμμ 맨 μμ μΆκ°ν΄μΌ ν©λλ€. pre-commit μ check-executables-have-shebangs
νν¬μ κ°μ λꡬλ₯Ό μ¬μ©νμ¬ μ΄λ₯Ό μ μ©ν μ μμ΅λλ€.
μ€ν¬λ¦½νΈλ₯Ό μ§μ μ€ννμ§ μμΌλ €κ³ λμ python script.py
λ₯Ό μꡬνλ €λ©΄ μ€ν κ°λ₯μΌλ‘ νμνμ§ μμμΌ ν©λλ€.
λ΄κ° λ§νλ―μ΄, λλ μ¬κΈ°μ μ£Όμ λ Όλ¦¬μ λμν©λλ€. λλ μ€λ₯κ° μ²λ¦¬λλ λ°©μκ³Ό κΈ°μ μ μΈ μΈλΆ μ¬νμ μμ§ λͺ»νκ±°λ μ½λλ₯Ό μ½μ§ μλ ν μ€λ₯ λ©μμ§λ₯Ό μ΄ν΄ν μ μλ€λ μ¬μ€μ λμνμ§ μμ΅λλ€. μ΅μν λ³κ²½ λ‘κ·Έμ λ¬Έμνλμ΄μΌ ν©λλ€.
μ°λ¦¬λ Linuxμμ μ€λ μ€λ₯ λ©μμ§λ₯Ό μ μ΄ν μ μμ΅λλ€. μ€ν νμΌμ΄ μ²λ¦¬λλ λ°©μμ λ³κ²½νλ€λ μ¬μ€μ΄ λ³κ²½ λ‘κ·Έμ λμ΄λ©λλ€.
Python νμΌμ΄ μ€ν κ°λ₯μΌλ‘ νμλ κ²½μ° λ¦¬λ‘λλ Python μ€ν νμΌμ λͺ λ Ήμ€ μμ μΆκ°νμ§ μμ΅λλ€. μ΄λ κ² νλ©΄ 리λ‘λκ° NixOSμμ μλν μ μμ΅λλ€. #1242
νμΌμ μ€ν λΆκ°λ₯νκ² λ§λλ κ²μ΄ μλν©λλ€. shebang λΌμΈμ λλ₯Ό μν΄ κ·Έλ μ§ μμ΅λλ€. λμ νμΌμ μ°Ύμ μ μμ μ€λ₯κ° λ°μν©λλ€. κ·Έκ²μ΄ λ΄κ° μλν 첫 λ²μ§Έ μΌμ΄μμ΅λλ€.
#!/usr/bin/env python3
μ¬μ©:
Ξ» docker run flask_test
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
: No such file or directory
λν νλμ Linux λ°°ν¬νμμλ§ μλνμ§λ§ λλ¨Έμ§λ μ€λ¨νλ λ³κ²½μ΄ μ΄μμ μ΄μ§ μλ€κ³ μκ°ν©λλ€. νμΌμ μ€ν κ°λ₯νμ§ μκ² λ§λλ κ²μ΄ μ μ ν ν΄κ²°μ± μΈ κ² κ°μ§λ§ μ¬μ ν λμκ²λ μ΄κ²μ΄ κΉ¨μ Έ 보μ λλ€.
@penner42 μλ #!/usr/bin/env νμ΄μ¬
root<strong i="7">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python3
lrwxrwxrwx 1 root staff 9 Mar 4 23:40 /usr/local/bin/python3 -> python3.6
root<strong i="8">@4541ebd677e0</strong>:/usr/src/app# ls -la /usr/local/bin/python
lrwxrwxrwx 1 root staff 7 Mar 4 23:40 /usr/local/bin/python -> python3
μλ§λ python3μ symlinkκ° μμ κ²μ λλ€.
κ°μ κ²°κ³Όμ
λλ€. python3 symlinkκ° μμΌλ©° μ
Έμμ /usr/bin/env python3
λλ /usr/bin/env python
λ₯Ό μ€ννκΈ°λ§ νλ©΄ λ©λλ€.
FWIW, Dockerλ λΉλν λ μ΄ κ²½κ³ λ₯Ό νμν©λλ€.
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
flask run
λͺ
λ Ήμ μ¬μ©ν©λλ€.
FROM python:3.7-alpine
WORKDIR /app
ENV FLASK_ENV development
ENV FLASK_APP example
EXPOSE 5000
RUN ["pip", "install", "flask"]
CMD ["flask", "run", "-h", "0.0.0.0"]
docker run --rm -p 5000:5000 -v $(pwd):/app flask/example:latest
https://docs.docker.com/compose/gettingstarted/ μ μμ΅μκ° Windows 7μμ μλνλ λ° μ¬μ©λμμ΅λκΉ?
μ΄ μ΅κ·Ό λ³κ²½ μ¬νμ΄ μμ λ₯Ό μ€ννλ €κ³ μλνλ λμ μ μ¬ν μ€λ₯κ° νμλλ μ΄μ μ
λκΉ?
$ docker-compose up
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
redis_1 | 1:C 27 Mar 2019 17:29:12.746 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 27 Mar 2019 17:29:12.746 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 27 Mar 2019 17:29:12.747 # Warning: no config file specified, using the default config. In order to specify a config file use redis-ser
ver /path/to/redis.conf
redis_1 | 1:M 27 Mar 2019 17:29:12.757 * Running mode=standalone, port=6379.
redis_1 | 1:M 27 Mar 2019 17:29:12.757 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to th
e lower value of 128.
redis_1 | 1:M 27 Mar 2019 17:29:12.758 # Server initialized
redis_1 | 1:M 27 Mar 2019 17:29:12.758 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issu
e add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
web_1 | * Serving Flask app "app" (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: Do not use the development server in a production environment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: on
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | Traceback (most recent call last):
web_1 | File "app.py", line 32, in <module>
web_1 | app.run(host="0.0.0.0", debug=True)
web_1 | File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 943, in run
web_1 | run_simple(host, port, self, **options)
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/serving.py", line 988, in run_simple
web_1 | run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 332, in run_with_reloader
web_1 | sys.exit(reloader.restart_with_reloader())
web_1 | File "/usr/local/lib/python3.4/site-packages/werkzeug/_reloader.py", line 176, in restart_with_reloader
web_1 | exit_code = subprocess.call(args, env=new_environ, close_fds=False)
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 534, in call
web_1 | with Popen(*popenargs, **kwargs) as p:
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 856, in __init__
web_1 | restore_signals, start_new_session)
web_1 | File "/usr/local/lib/python3.4/subprocess.py", line 1464, in _execute_child
web_1 | raise child_exception_type(errno_num, err_msg)
web_1 | OSError: [Errno 8] Exec format error
composetest_web_1 exited with code 1
λμΌν νν 리μΌμ μννκ³ λμΌν λ¬Έμ λ₯Ό λ°κ²¬νμ΅λλ€. μ΄κ²μ λλ₯Ό μν΄ κ·Έκ²μ κ³ μ³€μ΅λλ€.
app.py
μ€ν¬λ¦½νΈ μλ¨μ λ€μ shebangμ μΆκ°νμ΅λλ€.
#!/usr/local/bin/python3
κ·Έλ° λ€μ κΆν λ¬Έμ κ° λ°μνμ΅λλ€. κ·Έλ° λ€μ CMD μ μ Dockerfile
μ λ€μμ μΆκ°νμ΅λλ€.
RUN chmod 644 app.py
λꡬλ μ§ νν 리μΌμ μ
λ°μ΄νΈν μ μμ΅λλ€(https://docs.docker.com/compose/gettingstarted/).
μΆκ°νλ€
RUN chmod 644 app.py
λꡬ 0.15.5μμ μμ λμμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
λμΌν νν 리μΌμ μννκ³ λμΌν λ¬Έμ λ₯Ό λ°κ²¬νμ΅λλ€. μ΄κ²μ λλ₯Ό μν΄ κ·Έκ²μ κ³ μ³€μ΅λλ€.
app.py
μ€ν¬λ¦½νΈ μλ¨μ λ€μ shebangμ μΆκ°νμ΅λλ€.#!/usr/local/bin/python3
κ·Έλ° λ€μ κΆν λ¬Έμ κ° λ°μνμ΅λλ€. κ·Έλ° λ€μ CMD μ μ
Dockerfile
μ λ€μμ μΆκ°νμ΅λλ€.RUN chmod 644 app.py