- name: Deploy Learning Platform with Ansible hosts: all become: yes gather_facts: yes vars: ansible_ssh_common_args: '-o StrictHostKeyChecking=no' tasks: - name: Set destination directory ansible.builtin.set_fact: dest_dir: "/opt/learning-platform" - name: Ensure dependencies are installed ansible.builtin.package: name: - docker-ce state: present ignore_errors: yes register: docker_valid - name: Include geerlingguy.docker role conditionally include_role: name: geerlingguy.docker when: docker_valid is failed - name: Ensure target directory exists ansible.builtin.file: path: "{{ dest_dir }}" state: directory owner: root group: root mode: "0755" - name: Copy compose.yml to destination ansible.builtin.copy: src: compose.yml dest: "{{ dest_dir }}/compose.yml" - name: Copy pb_migrations to destination ansible.builtin.copy: src: ../../../pb_migrations dest: "{{ dest_dir }}/" mode: "0755" - name: Copy pb_hooks to destination ansible.builtin.copy: src: ../../../pb_hooks dest: "{{ dest_dir }}/" mode: "0755" - name: Create .env file for secrets ansible.builtin.copy: dest: "{{ dest_dir }}/.env" content: | ANTHROPIC_API_KEY={{ anthropic_api_key | default('') }} ENTRA_TENANT_ID={{ entra_tenant_id | default('') }} ENTRA_CLIENT_ID={{ entra_client_id | default('') }} ENTRA_CLIENT_SECRET={{ entra_client_secret | default('') }} ENTRA_ADMIN_EMAILS={{ entra_admin_emails | default('') }} mode: '0600' - name: Pull latest image community.docker.docker_compose_v2: project_src: "{{ dest_dir }}" state: present files: compose.yml pull: always - name: Start services with Docker Compose community.docker.docker_compose_v2: project_src: "{{ dest_dir }}" state: present files: compose.yml recreate: always # A failed migration aborts `pocketbase serve` and the container crash-loops # while `docker compose up` still reports success (issue #18). Gate the # deploy on PocketBase actually serving its health endpoint. - name: Wait for PocketBase to become healthy ansible.builtin.command: docker exec pocketbase-learning wget -q -O - http://127.0.0.1:8090/api/health register: pb_health until: pb_health.rc == 0 retries: 18 delay: 5 changed_when: false ignore_errors: yes - name: Collect PocketBase logs for diagnosis ansible.builtin.command: docker logs --tail 80 pocketbase-learning register: pb_logs when: pb_health is failed changed_when: false failed_when: false - name: Abort deploy — PocketBase is not healthy ansible.builtin.fail: msg: | PocketBase did not become healthy after the deploy (health endpoint unreachable). Recent container logs: {{ pb_logs.stdout | default('') }} {{ pb_logs.stderr | default('') }} when: pb_health is failed