Python in a container with Gunicorn

https://code.visualstudio.com/docs/containers/quickstart-python

Use Docker Compose with docker-compose.debug.yml

https://code.visualstudio.com/docs/containers/docker-compose#_debug

tasks.json

  1. {
  2. "version": "2.0.0",
  3. "tasks": [
  4. {
  5. "type": "docker-build",
  6. "label": "docker-build",
  7. "platform": "python",
  8. "dockerBuild": {
  9. "tag": "helloflask:latest",
  10. "dockerfile": "${workspaceFolder}/Dockerfile",
  11. "context": "${workspaceFolder}",
  12. "pull": true
  13. }
  14. },
  15. {
  16. "type": "docker-run",
  17. "label": "docker-run: debug",
  18. "dependsOn": [
  19. "docker-build"
  20. ],
  21. "dockerRun": {
  22. "env": {
  23. "FLASK_APP": "app.py",
  24. "FLASK_ENV": "development"
  25. },
  26. "volumes": [
  27. {
  28. "containerPath": "/app", "localPath": "${workspaceFolder}"
  29. }
  30. ]
  31. },
  32. "python": {
  33. "args": [
  34. "run",
  35. "--host", "0.0.0.0",
  36. "--port", "5000"
  37. ],
  38. "module": "flask"
  39. }
  40. }
  41. ]
  42. }

launch.json

  1. {
  2. // Use IntelliSense to learn about possible attributes.
  3. // Hover to view descriptions of existing attributes.
  4. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  5. "version": "0.2.0",
  6. "configurations": [
  7. {
  8. "name": "Python: Remote Attach",
  9. "type": "python",
  10. "request": "attach",
  11. "port": 5678,
  12. "host": "localhost",
  13. "pathMappings": [
  14. {
  15. "localRoot": "${workspaceFolder}",
  16. "remoteRoot": "/app"
  17. }
  18. ]
  19. },
  20. {
  21. "name": "Python: Flask",
  22. "type": "python",
  23. "request": "launch",
  24. "module": "flask",
  25. "env": {
  26. "FLASK_APP": "app.py",
  27. "FLASK_ENV": "development",
  28. "FLASK_DEBUG": "0"
  29. },
  30. "args": [
  31. "run",
  32. "--no-debugger",
  33. "--no-reload"
  34. ],
  35. "jinja": true
  36. },
  37. {
  38. "name": "Docker: Python - Flask",
  39. "type": "docker",
  40. "request": "launch",
  41. "preLaunchTask": "docker-run: debug",
  42. "python": {
  43. "pathMappings": [
  44. {
  45. "localRoot": "${workspaceFolder}",
  46. "remoteRoot": "/app"
  47. }
  48. ],
  49. "projectType": "flask"
  50. }
  51. }
  52. ]
  53. }

docker-compose.debug.yml

  1. version: '3.4'
  2. services:
  3. helloflask:
  4. image: helloflask
  5. build:
  6. context: .
  7. dockerfile: ./Dockerfile
  8. command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m flask run --no-debugger --no-reload --host 0.0.0.0 --port 5000"]
  9. ports:
  10. - 5000:5000
  11. - 5678:5678
  12. environment:
  13. - FLASK_APP=app.py
  14. - FLASK_ENV=development

docker-compose.yml

  1. version: '3.4'
  2. services:
  3. helloflask:
  4. image: helloflask
  5. build:
  6. context: .
  7. dockerfile: ./Dockerfile
  8. ports:
  9. - 5000:5000
  10. networks:
  11. - net-proxy
  12. networks:
  13. net-proxy:
  14. # external: true,告知dockerd我们需要使用外部网络(卷、秘钥等也有类似操作),无需自动帮我创建net-proxy
  15. external: true
  16. # 告知dockerd我们使用my-proxy-net的网络,因此web服务可以与my-proxy-net容器互联
  17. name: my-proxy-net

Dockerfile

  1. # For more information, please refer to https://aka.ms/vscode-docker-python
  2. FROM python:3.8-slim-buster
  3. EXPOSE 5000
  4. # Keeps Python from generating .pyc files in the container
  5. ENV PYTHONDONTWRITEBYTECODE=1
  6. # Turns off buffering for easier container logging
  7. ENV PYTHONUNBUFFERED=1
  8. # Install pip requirements
  9. ADD requirements.txt .
  10. RUN python -m pip install -r requirements.txt
  11. WORKDIR /app
  12. ADD . /app
  13. # Switching to a non-root user, please refer to https://aka.ms/vscode-docker-python-user-rights
  14. RUN useradd appuser && chown -R appuser /app
  15. USER appuser
  16. # During debugging, this entry point will be overridden. For more information, please refer to https://aka.ms/vscode-docker-python-debug
  17. CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]