Skip to content

Instantly share code, notes, and snippets.

@gemmadlou
Created September 16, 2024 13:09
Show Gist options
  • Save gemmadlou/002faaf35bec7d25d08ca445a3efe0ba to your computer and use it in GitHub Desktop.
Save gemmadlou/002faaf35bec7d25d08ca445a3efe0ba to your computer and use it in GitHub Desktop.
Deploy Laravel Application with Zero Downtime
---
- name: Deploy Laravel Application with Zero Downtime
hosts: web
become: yes
vars:
app_name: "domain"
deploy_user: deployer
deploy_group: www-data
deploy_dir: "/var/www/{{ app_name }}.com"
local_app_dir: "{{ playbook_dir | dirname | dirname }}"
release_date_time: "{{ ansible_date_time.iso8601_basic_short }}" # e.g., 202409161307
release_dir: "{{ deploy_dir }}/releases/{{ release_date_time }}"
current_dir: "{{ deploy_dir }}/current"
shared_dir: "{{ deploy_dir }}/shared"
tasks:
- name: Ensure directories exist
file:
path: "{{ item }}"
state: directory
mode: '0755'
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
loop:
- "{{ deploy_dir }}"
- "{{ release_dir }}"
- "{{ shared_dir }}/storage"
- "{{ shared_dir }}/storage/logs"
- "{{ shared_dir }}/storage/app"
- "{{ shared_dir }}/storage/app/public"
- "{{ shared_dir }}/storage/framework"
- "{{ shared_dir }}/storage/framework/cache"
- "{{ shared_dir }}/storage/framework/sessions"
- "{{ shared_dir }}/storage/framework/views"
- name: Ensure .env file exists
file:
path: "{{ shared_dir }}/.env"
state: touch
mode: '0644'
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
- name: Run npm install locally
local_action:
module: command
cmd: npm install
args:
chdir: "{{ local_app_dir }}"
become: no # Ensure sudo is not used for this task
- name: Build the project in the release directory
local_action:
module: command
cmd: npm run build
args:
chdir: "{{ local_app_dir }}"
become: no # Ensure sudo is not used for this task
- name: Copy Laravel project to the server
synchronize:
src: "{{ local_app_dir }}/"
dest: "{{ release_dir }}/"
delete: yes
rsync_opts:
- "--exclude=.git"
- "--exclude=node_modules"
- "--exclude=vendor"
- "--exclude=_ansible"
- "--exclude=storage"
- "--exclude=database/database.sqlite"
- name: Create symlink for SQLite database
command: >
ln -sfn {{ shared_dir }}/database/database.sqlite {{ release_dir }}/database/database.sqlite
args:
creates: "{{ release_dir }}/database/database.sqlite"
- name: Create symlink for Storage
command: >
ln -sfn {{ shared_dir }}/storage {{ release_dir }}/storage
- name: Set ownership for new release
file:
path: "{{ release_dir }}"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
recurse: yes
- name: Copy .env file
copy:
src: "{{ release_dir }}/.env.production"
dest: "{{ release_dir }}/.env"
remote_src: yes
- name: Set permissions for storage and bootstrap cache
file:
path: "{{ release_dir }}/{{ item }}"
state: directory
mode: '0775'
recurse: yes
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
loop:
- storage
- bootstrap/cache
- database
- name: Run Composer install
composer:
command: install
working_dir: "{{ release_dir }}"
prefer_dist: yes
no_dev: yes
optimize_autoloader: yes
become_user: "{{ deploy_user }}"
- name: Set permissions sqlite db
file:
path: "{{ release_dir }}/{{ item }}"
state: file
mode: '0775'
owner: "{{ deploy_user }}"
group: "{{ deploy_group }}"
loop:
- database/database.sqlite
- name: Run Laravel migrations (optional)
command: "php artisan migrate --force"
args:
chdir: "{{ release_dir }}"
- name: Create the new release
command: >
ln -sfn {{ release_dir }} {{ current_dir }}
- name: Reload PHP-FPM service
service:
name: "php8.3-fpm.service"
state: reloaded
- name: Reload Nginx service
service:
name: "nginx"
state: reloaded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment