182 lines
6.0 KiB
YAML
182 lines
6.0 KiB
YAML
---
|
|
# Git-Based Production Deployment Playbook
|
|
# Uses Git to sync files, builds image, and updates services
|
|
# Usage: ansible-playbook -i inventory/production.yml playbooks/deploy-complete-git.yml
|
|
|
|
- name: Git-Based Production Deployment
|
|
hosts: production_server
|
|
become: no
|
|
vars:
|
|
# Calculate project root: playbook is in deployment/ansible/playbooks/, go up 3 levels
|
|
local_project_path: "{{ playbook_dir }}/../../.."
|
|
remote_project_path: /home/deploy/framework-app
|
|
docker_registry: localhost:5000
|
|
docker_image_name: framework
|
|
docker_image_tag: latest
|
|
docker_stack_name: framework
|
|
build_timestamp: "{{ ansible_date_time.epoch }}"
|
|
|
|
tasks:
|
|
- name: Display deployment information
|
|
debug:
|
|
msg:
|
|
- "🚀 Starting Git-Based Deployment"
|
|
- "Local Path: {{ local_project_path }}"
|
|
- "Remote Path: {{ remote_project_path }}"
|
|
- "Image: {{ docker_registry }}/{{ docker_image_name }}:{{ docker_image_tag }}"
|
|
- "Timestamp: {{ build_timestamp }}"
|
|
|
|
- name: Create remote project directory
|
|
file:
|
|
path: "{{ remote_project_path }}"
|
|
state: directory
|
|
mode: '0755'
|
|
|
|
- name: Check if Git repository exists on production
|
|
stat:
|
|
path: "{{ remote_project_path }}/.git"
|
|
register: git_repo
|
|
|
|
- name: Initialize Git repository if not exists
|
|
shell: |
|
|
cd {{ remote_project_path }}
|
|
git init
|
|
git config user.email 'deploy@michaelschiemer.de'
|
|
git config user.name 'Deploy User'
|
|
when: not git_repo.stat.exists
|
|
|
|
- name: Create tarball of current code (excluding unnecessary files)
|
|
delegate_to: localhost
|
|
shell: |
|
|
cd {{ local_project_path }}
|
|
tar czf /tmp/framework-deploy-{{ build_timestamp }}.tar.gz \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='vendor' \
|
|
--exclude='storage/logs/*' \
|
|
--exclude='storage/cache/*' \
|
|
--exclude='.env' \
|
|
--exclude='.env.*' \
|
|
--exclude='tests' \
|
|
--exclude='.deployment-backup' \
|
|
--exclude='deployment' \
|
|
.
|
|
register: tarball_creation
|
|
changed_when: true
|
|
|
|
- name: Transfer tarball to production
|
|
copy:
|
|
src: "/tmp/framework-deploy-{{ build_timestamp }}.tar.gz"
|
|
dest: "/tmp/framework-deploy-{{ build_timestamp }}.tar.gz"
|
|
register: tarball_transfer
|
|
|
|
- name: Extract tarball to production (preserving Git)
|
|
shell: |
|
|
cd {{ remote_project_path }}
|
|
tar xzf /tmp/framework-deploy-{{ build_timestamp }}.tar.gz
|
|
rm -f /tmp/framework-deploy-{{ build_timestamp }}.tar.gz
|
|
register: extraction_result
|
|
changed_when: true
|
|
|
|
- name: Commit changes to Git repository
|
|
shell: |
|
|
cd {{ remote_project_path }}
|
|
git add -A
|
|
git commit -m "Deployment {{ build_timestamp }}" || echo "No changes to commit"
|
|
git log --oneline -5
|
|
register: git_commit
|
|
changed_when: true
|
|
|
|
- name: Display Git status
|
|
debug:
|
|
msg: "{{ git_commit.stdout_lines }}"
|
|
|
|
- name: Clean up local tarball
|
|
delegate_to: localhost
|
|
file:
|
|
path: "/tmp/framework-deploy-{{ build_timestamp }}.tar.gz"
|
|
state: absent
|
|
|
|
- name: Build Docker image on production server
|
|
shell: |
|
|
cd {{ remote_project_path }}
|
|
docker build \
|
|
-f docker/php/Dockerfile \
|
|
--target production \
|
|
-t {{ docker_registry }}/{{ docker_image_name }}:{{ docker_image_tag }} \
|
|
-t {{ docker_registry }}/{{ docker_image_name }}:{{ build_timestamp }} \
|
|
--no-cache \
|
|
--progress=plain \
|
|
.
|
|
register: build_result
|
|
changed_when: true
|
|
|
|
- name: Display build output (last 20 lines)
|
|
debug:
|
|
msg: "{{ build_result.stdout_lines[-20:] }}"
|
|
|
|
- name: Update web service with rolling update
|
|
shell: |
|
|
docker service update \
|
|
--image {{ docker_registry }}/{{ docker_image_name }}:{{ docker_image_tag }} \
|
|
--force \
|
|
--update-parallelism 1 \
|
|
--update-delay 10s \
|
|
{{ docker_stack_name }}_web
|
|
register: web_update
|
|
changed_when: true
|
|
|
|
- name: Update queue-worker service
|
|
shell: |
|
|
docker service update \
|
|
--image {{ docker_registry }}/{{ docker_image_name }}:{{ docker_image_tag }} \
|
|
--force \
|
|
{{ docker_stack_name }}_queue-worker
|
|
register: worker_update
|
|
changed_when: true
|
|
|
|
- name: Wait for services to stabilize (30 seconds)
|
|
pause:
|
|
seconds: 30
|
|
prompt: "Waiting for services to stabilize..."
|
|
|
|
- name: Check service status
|
|
shell: docker stack services {{ docker_stack_name }} --format "table {{`{{.Name}}\t{{.Replicas}}\t{{.Image}}`}}"
|
|
register: service_status
|
|
changed_when: false
|
|
|
|
- name: Check website availability
|
|
shell: curl -k -s -o /dev/null -w '%{http_code}' https://michaelschiemer.de/
|
|
register: website_check
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Get recent web service logs
|
|
shell: docker service logs {{ docker_stack_name }}_web --tail 10 --no-trunc 2>&1 | tail -20
|
|
register: web_logs
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Display deployment summary
|
|
debug:
|
|
msg:
|
|
- "✅ Git-Based Deployment Completed"
|
|
- ""
|
|
- "Build Timestamp: {{ build_timestamp }}"
|
|
- "Image: {{ docker_registry }}/{{ docker_image_name }}:{{ docker_image_tag }}"
|
|
- ""
|
|
- "Git Commit Info:"
|
|
- "{{ git_commit.stdout_lines }}"
|
|
- ""
|
|
- "Service Status:"
|
|
- "{{ service_status.stdout_lines }}"
|
|
- ""
|
|
- "Website HTTP Status: {{ website_check.stdout }}"
|
|
- ""
|
|
- "Recent Logs:"
|
|
- "{{ web_logs.stdout_lines }}"
|
|
- ""
|
|
- "🌐 Website: https://michaelschiemer.de"
|
|
- "📊 Portainer: https://michaelschiemer.de:9000"
|
|
- "📈 Grafana: https://michaelschiemer.de:3000"
|