如何通过Ansible实现在tmux会话中启动Django项目的gunicorn服务
你猜测的原因是对的,默认执行tmux new-session会进入attach模式,占据当前shell进程不返回,因此Ansible会持续等待命令执行结束,出现卡住的现象。
解决方案
只需要给tmux命令加上detached参数,让操作后台执行立刻返回,再通过tmux的内置命令把gunicorn启动指令发送到对应会话即可,不需要手动执行tmux相关操作。
以下是两种常用的playbook实现方式:
写法1:创建会话时直接指定启动命令(推荐,逻辑更简洁)
直接在创建tmux会话时加-d参数后台运行,同时指定会话内要执行的命令,示例task如下:
- name: 启动tmux会话并运行gunicorn ansible.builtin.shell: | tmux new-session -A -s api -d 'source /path/to/your/venv/bin/activate && gunicorn --bind 0.0.0.0:8000 your_project.wsgi:application' args: chdir: /path/to/your/django/project
如果不需要虚拟环境激活,直接写gunicorn的全路径也可以,和你之前解决virtualenv启动问题的逻辑一致。
写法2:分步骤创建会话、发送启动命令
如果需要在会话内执行多条指令,可以分两步操作:
- name: 后台创建tmux会话 ansible.builtin.shell: tmux new-session -A -s api -d - name: 向tmux会话发送gunicorn启动命令 ansible.builtin.shell: | tmux send-keys -t api 'source /path/to/your/venv/bin/activate' C-m tmux send-keys -t api 'cd /path/to/your/django/project' C-m tmux send-keys -t api 'gunicorn --bind 0.0.0.0:8000 your_project.wsgi:application' C-m
其中C-m是tmux里的回车符,用来执行输入的命令。
补充说明
- 如果需要校验启动结果,可以加一个task执行
tmux capture-pane -t api -p,就能捕获会话内的输出内容,确认gunicorn是否启动成功。 - 生产环境更推荐用systemd托管gunicorn进程,原生支持开机自启、崩溃自动重启、日志落盘等能力,比tmux手动管理更稳定。如果只是需要临时查看运行时输出,保留tmux的方案也完全可用。
内容的提问来源于stack exchange,提问作者alexakarpov
相关产品推荐
相关产品推荐

