/
/
/
1---
2# Runner Services - Ghost CMS (Headless Content Management)
3
4- name: Create Ghost configuration directories
5 file:
6 path: "{{ item }}"
7 state: directory
8 owner: "{{ runner_user }}"
9 group: "users"
10 mode: '2775' # setgid bit for inheritance, group writable (umask 002)
11 loop:
12 - "{{ ghost_config_dir }}"
13 - "{{ ghost_config_dir }}/mysql"
14 - "{{ ghost_data_dir }}"
15 - "{{ ghost_content_dir }}"
16 - "{{ ghost_content_dir }}/themes"
17 - "{{ ghost_content_dir }}/images"
18 - "{{ ghost_content_dir }}/files"
19 - "{{ ghost_content_dir }}/adapters"
20
21- name: Generate Ghost environment file
22 template:
23 src: ghost.env.j2
24 dest: "{{ ghost_config_dir }}/ghost.env"
25 owner: "{{ runner_user }}"
26 group: "{{ runner_group }}"
27 mode: '0664'
28 notify: restart ghost
29
30- name: Create Ghost configuration file
31 template:
32 src: ghost-config.json.j2
33 dest: "{{ ghost_content_dir }}/config.production.json"
34 owner: "{{ runner_user }}"
35 group: "{{ runner_group }}"
36 mode: '0664'
37 notify: restart ghost
38
39
40- name: Create Ghost Docker Compose file
41 template:
42 src: ghost-compose.yml.j2
43 dest: "{{ ghost_config_dir }}/docker-compose.yml"
44 owner: "{{ runner_user }}"
45 group: "{{ runner_group }}"
46 mode: '0664'
47 notify: restart ghost
48
49- name: Check if Ghost is already running
50 community.docker.docker_compose_v2:
51 project_src: "{{ ghost_config_dir }}"
52 state: present
53 restarted: false
54 register: ghost_running
55 changed_when: false
56 failed_when: false
57
58- name: Start Ghost services (MySQL + Ghost)
59 community.docker.docker_compose_v2:
60 project_src: "{{ ghost_config_dir }}"
61 state: present
62 register: ghost_start_result
63
64
65- name: Wait for Ghost to be healthy
66 uri:
67 url: "http://localhost:{{ ghost_port }}/ghost/api/admin/site/"
68 method: GET
69 status_code: [200, 403] # 403 is OK for unauthenticated API access
70 register: ghost_health
71 until: ghost_health.status in [200, 403]
72 retries: 30
73 delay: 10
74 when: ghost_start_result is changed
75
76
77
78
79- name: Display Ghost CMS deployment summary
80 debug:
81 msg: |
82 Ghost CMS (Headless) Deployment:
83 - Status: {{ 'Started' if ghost_start_result is changed else 'Already running' }}
84 - Admin Interface: http://{{ ansible_default_ipv4.address }}:{{ ghost_port }}/ghost/
85 - Website: http://{{ ansible_default_ipv4.address }}:{{ ghost_port }}
86 - Content API: http://{{ ansible_default_ipv4.address }}:{{ ghost_port }}/ghost/api/content/
87 - Admin API: http://{{ ansible_default_ipv4.address }}:{{ ghost_port }}/ghost/api/admin/
88 - Database: MySQL {{ mysql_version }}
89 - Configuration: {{ ghost_content_dir }}/config.production.json
90 - Content Storage: {{ ghost_content_dir }}
91 - Database Data: {{ mysql_config_dir }}
92 - Site URL: {{ ghost_url }}
93
94 API Endpoints (for website integration):
95 - Posts: /ghost/api/content/posts/
96 - Pages: /ghost/api/content/pages/
97 - Tags: /ghost/api/content/tags/
98 - Authors: /ghost/api/content/authors/
99 - Settings: /ghost/api/content/settings/
100
101 Features:
102 - Headless CMS for websites and apps
103 - RESTful Content API
104 - Admin API for management
105 - Built-in themes and customization
106 - SEO optimization
107 - Email newsletter integration
108 - Member management and subscriptions
109
110 Management Commands:
111 - ghost-logs.sh - View service logs
112 - ghost-restart.sh - Restart services
113 - ghost-status.sh - Check service status
114 - ghost-backup.sh - Backup content and database
115 - ghost-cli.sh - Ghost CLI commands
116 - ghost-mysql.sh - MySQL management
117 - ghost-api-examples.sh - API usage examples
118
119 Initial Setup:
120 1. Visit http://{{ ansible_default_ipv4.address }}:{{ ghost_port }}/ghost/
121 2. Create your admin account
122 3. Configure your publication settings
123 4. Set up your theme and branding
124 5. Create your first content
125 6. Configure API keys for external access
126
127 Headless/API Integration:
128 - Use Content API key for read-only access
129 - Use Admin API key for content management
130 - Webhook support for real-time updates
131 - JSON responses for all content types
132 - GraphQL support available via plugins