feat(playbooks): add codex and opencode acp roles

This commit is contained in:
Haitao Pan 2026-04-04 13:44:16 +08:00
parent f7a627673a
commit 0f0b7cfd04
22 changed files with 358 additions and 0 deletions

View File

@ -0,0 +1,7 @@
---
- name: Deploy OpenCode ACP vhosts
hosts: all
become: true
gather_facts: true
roles:
- roles/vhosts/acp_opencode/

View File

@ -0,0 +1,7 @@
---
- name: Deploy Codex ACP vhosts
hosts: all
become: true
gather_facts: true
roles:
- roles/vhosts/acp_codex/

View File

@ -0,0 +1,13 @@
# acp_codex
Minimal Codex ACP deployment role.
Installs:
- `caddy`
- `bubblewrap`
Exposes:
- `codex app-server --listen ws://127.0.0.1:9001`
- `https://acp-server-codex.svc.plus`

View File

@ -0,0 +1,15 @@
---
acp_codex_service_name: codex-app-server
acp_codex_service_user: root
acp_codex_service_group: root
acp_codex_workdir: /root
acp_codex_listen_host: 127.0.0.1
acp_codex_listen_port: 9001
acp_codex_domain: acp-server-codex.svc.plus
acp_codex_caddyfile_path: /etc/caddy/Caddyfile
acp_codex_caddy_conf_dir: /etc/caddy/conf.d
acp_codex_caddy_fragment_path: /etc/caddy/conf.d/acp-server-codex.caddy
acp_codex_enable_ufw: true
acp_codex_packages:
- caddy
- bubblewrap

View File

@ -0,0 +1,10 @@
---
- name: Reload caddy
ansible.builtin.service:
name: caddy
state: reloaded
- name: Restart codex app server
ansible.builtin.service:
name: "{{ acp_codex_service_name }}"
state: restarted

View File

@ -0,0 +1,43 @@
---
- name: Deploy Caddy main file
ansible.builtin.template:
src: Caddyfile.j2
dest: "{{ acp_codex_caddyfile_path }}"
owner: root
group: root
mode: "0644"
notify: Reload caddy
- name: Deploy Codex ACP Caddy site
ansible.builtin.template:
src: acp-site.caddy.j2
dest: "{{ acp_codex_caddy_fragment_path }}"
owner: root
group: root
mode: "0644"
notify: Reload caddy
- name: Deploy Codex ACP systemd service
ansible.builtin.template:
src: codex-app-server.service.j2
dest: "/etc/systemd/system/{{ acp_codex_service_name }}.service"
owner: root
group: root
mode: "0644"
notify: Restart codex app server
- name: Reload systemd manager configuration
ansible.builtin.systemd:
daemon_reload: true
- name: Ensure Caddy is enabled and running
ansible.builtin.systemd:
name: caddy
enabled: true
state: started
- name: Ensure Codex ACP service is enabled and running
ansible.builtin.systemd:
name: "{{ acp_codex_service_name }}"
enabled: true
state: started

View File

@ -0,0 +1,34 @@
---
- name: Install Codex ACP packages
ansible.builtin.apt:
name: "{{ acp_codex_packages }}"
state: present
update_cache: true
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
become: true
- name: Ensure Caddy conf directory exists
ansible.builtin.file:
path: "{{ acp_codex_caddy_conf_dir }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Open HTTP and HTTPS ports when UFW is enabled
ansible.builtin.command: ufw allow 80/tcp
register: acp_codex_ufw_80
changed_when: "'Rule added' in acp_codex_ufw_80.stdout"
failed_when: acp_codex_ufw_80.rc != 0
when:
- acp_codex_enable_ufw | bool
- name: Open HTTPS port when UFW is enabled
ansible.builtin.command: ufw allow 443/tcp
register: acp_codex_ufw_443
changed_when: "'Rule added' in acp_codex_ufw_443.stdout"
failed_when: acp_codex_ufw_443.rc != 0
when:
- acp_codex_enable_ufw | bool

View File

@ -0,0 +1,12 @@
---
- name: Install Codex ACP prerequisites
ansible.builtin.import_tasks: install.yml
tags: [acp_codex, acp_codex_install]
- name: Configure Codex ACP service and Caddy
ansible.builtin.import_tasks: config.yml
tags: [acp_codex, acp_codex_config]
- name: Validate Codex ACP readiness
ansible.builtin.import_tasks: validate.yml
tags: [acp_codex, acp_codex_validate]

View File

@ -0,0 +1,23 @@
---
- name: Validate Caddy configuration
ansible.builtin.command: caddy validate --config "{{ acp_codex_caddyfile_path }}"
changed_when: false
- name: Check Codex app server listener
ansible.builtin.command: ss -ltnp
register: acp_codex_ss
changed_when: false
- name: Show Codex ACP status
ansible.builtin.command: systemctl status "{{ acp_codex_service_name }}" --no-pager
register: acp_codex_status
changed_when: false
failed_when: false
- name: Show Codex ACP validation summary
ansible.builtin.debug:
msg:
- "Codex domain: {{ acp_codex_domain }}"
- "Listener: {{ acp_codex_listen_host }}:{{ acp_codex_listen_port }}"
- "Service: {{ acp_codex_status.stdout | default('N/A') }}"
- "Socket: {{ acp_codex_ss.stdout | default('N/A') }}"

View File

@ -0,0 +1 @@
import {{ acp_codex_caddy_conf_dir }}/*.caddy

View File

@ -0,0 +1,3 @@
{{ acp_codex_domain }} {
reverse_proxy {{ acp_codex_listen_host }}:{{ acp_codex_listen_port }}
}

View File

@ -0,0 +1,19 @@
[Unit]
Description=Codex app server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User={{ acp_codex_service_user }}
Group={{ acp_codex_service_group }}
WorkingDirectory={{ acp_codex_workdir }}
Environment=HOME={{ acp_codex_workdir }}
Environment=TERM=xterm-256color
Environment=NODE_NO_WARNINGS=1
ExecStart=/usr/bin/codex app-server --listen ws://{{ acp_codex_listen_host }}:{{ acp_codex_listen_port }}
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,12 @@
# acp_opencode
Minimal OpenCode ACP deployment role.
Installs:
- `caddy`
Exposes:
- `opencode serve --hostname 127.0.0.1 --port 38992 --print-logs`
- `https://acp-server-opencode.svc.plus`

View File

@ -0,0 +1,15 @@
---
acp_opencode_service_name: opencode-acp
acp_opencode_service_user: ubuntu
acp_opencode_service_group: ubuntu
acp_opencode_home: /home/ubuntu
acp_opencode_workdir: /home/ubuntu/.opencode
acp_opencode_listen_host: 127.0.0.1
acp_opencode_listen_port: 38992
acp_opencode_domain: acp-server-opencode.svc.plus
acp_opencode_caddyfile_path: /etc/caddy/Caddyfile
acp_opencode_caddy_conf_dir: /etc/caddy/conf.d
acp_opencode_caddy_fragment_path: /etc/caddy/conf.d/acp-server-opencode.caddy
acp_opencode_enable_ufw: true
acp_opencode_packages:
- caddy

View File

@ -0,0 +1,10 @@
---
- name: Reload caddy
ansible.builtin.service:
name: caddy
state: reloaded
- name: Restart opencode acp
ansible.builtin.service:
name: "{{ acp_opencode_service_name }}"
state: restarted

View File

@ -0,0 +1,43 @@
---
- name: Deploy Caddy main file
ansible.builtin.template:
src: Caddyfile.j2
dest: "{{ acp_opencode_caddyfile_path }}"
owner: root
group: root
mode: "0644"
notify: Reload caddy
- name: Deploy OpenCode ACP Caddy site
ansible.builtin.template:
src: acp-site.caddy.j2
dest: "{{ acp_opencode_caddy_fragment_path }}"
owner: root
group: root
mode: "0644"
notify: Reload caddy
- name: Deploy OpenCode ACP systemd service
ansible.builtin.template:
src: opencode-acp.service.j2
dest: "/etc/systemd/system/{{ acp_opencode_service_name }}.service"
owner: root
group: root
mode: "0644"
notify: Restart opencode acp
- name: Reload systemd manager configuration
ansible.builtin.systemd:
daemon_reload: true
- name: Ensure Caddy is enabled and running
ansible.builtin.systemd:
name: caddy
enabled: true
state: started
- name: Ensure OpenCode ACP service is enabled and running
ansible.builtin.systemd:
name: "{{ acp_opencode_service_name }}"
enabled: true
state: started

View File

@ -0,0 +1,34 @@
---
- name: Install OpenCode ACP packages
ansible.builtin.apt:
name: "{{ acp_opencode_packages }}"
state: present
update_cache: true
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
become: true
- name: Ensure Caddy conf directory exists
ansible.builtin.file:
path: "{{ acp_opencode_caddy_conf_dir }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Open HTTP and HTTPS ports when UFW is enabled
ansible.builtin.command: ufw allow 80/tcp
register: acp_opencode_ufw_80
changed_when: "'Rule added' in acp_opencode_ufw_80.stdout"
failed_when: acp_opencode_ufw_80.rc != 0
when:
- acp_opencode_enable_ufw | bool
- name: Open HTTPS port when UFW is enabled
ansible.builtin.command: ufw allow 443/tcp
register: acp_opencode_ufw_443
changed_when: "'Rule added' in acp_opencode_ufw_443.stdout"
failed_when: acp_opencode_ufw_443.rc != 0
when:
- acp_opencode_enable_ufw | bool

View File

@ -0,0 +1,12 @@
---
- name: Install OpenCode ACP prerequisites
ansible.builtin.import_tasks: install.yml
tags: [acp_opencode, acp_opencode_install]
- name: Configure OpenCode ACP service and Caddy
ansible.builtin.import_tasks: config.yml
tags: [acp_opencode, acp_opencode_config]
- name: Validate OpenCode ACP readiness
ansible.builtin.import_tasks: validate.yml
tags: [acp_opencode, acp_opencode_validate]

View File

@ -0,0 +1,23 @@
---
- name: Validate Caddy configuration
ansible.builtin.command: caddy validate --config "{{ acp_opencode_caddyfile_path }}"
changed_when: false
- name: Check OpenCode ACP listener
ansible.builtin.command: ss -ltnp
register: acp_opencode_ss
changed_when: false
- name: Show OpenCode ACP status
ansible.builtin.command: systemctl status "{{ acp_opencode_service_name }}" --no-pager
register: acp_opencode_status
changed_when: false
failed_when: false
- name: Show OpenCode ACP validation summary
ansible.builtin.debug:
msg:
- "OpenCode domain: {{ acp_opencode_domain }}"
- "Listener: {{ acp_opencode_listen_host }}:{{ acp_opencode_listen_port }}"
- "Service: {{ acp_opencode_status.stdout | default('N/A') }}"
- "Socket: {{ acp_opencode_ss.stdout | default('N/A') }}"

View File

@ -0,0 +1 @@
import {{ acp_opencode_caddy_conf_dir }}/*.caddy

View File

@ -0,0 +1,3 @@
{{ acp_opencode_domain }} {
reverse_proxy {{ acp_opencode_listen_host }}:{{ acp_opencode_listen_port }}
}

View File

@ -0,0 +1,18 @@
[Unit]
Description=OpenCode ACP server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User={{ acp_opencode_service_user }}
Group={{ acp_opencode_service_group }}
WorkingDirectory={{ acp_opencode_workdir }}
Environment=HOME={{ acp_opencode_home }}
Environment=TERM=xterm-256color
ExecStart=/usr/bin/opencode serve --hostname {{ acp_opencode_listen_host }} --port {{ acp_opencode_listen_port }} --print-logs
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target