Giriş: Ansible ile Çoklu PHP Uygulama Dağıtımına Genel Bakış
Modern web geliştirme süreçlerinde, uygulamaların sunuculara hızlı, tutarlı ve hatasız bir şekilde dağıtılması kritik öneme sahiptir. Manuel dağıtım süreçleri zaman alıcı, hataya açık ve tekrarlanabilirliği düşüktür. Özellikle birden fazla PHP uygulamasını tek bir sunucuya veya birden fazla sunucuya dağıtmak gerektiğinde bu sorunlar daha da belirginleşir. İşte tam bu noktada Ansible gibi otomasyon araçları devreye girer.
Bu rehberde, Ansible kullanarak Ubuntu 14.04 işletim sistemine sahip bir sunucuya birden fazla PHP uygulamasını nasıl dağıtacağınızı adım adım inceleyeceğiz. Ubuntu 14.04 eski bir sürüm olmasına rağmen, Ansible’ın temel prensipleri ve rol tabanlı yaklaşımı bu platformda da sorunsuz bir şekilde uygulanabilir. Odak noktamız, farklı PHP uygulamalarının (farklı veritabanları, farklı Git depoları, farklı alan adları vb.) tek bir Ansible projesi içinde nasıl yönetileceği ve dağıtılacağı olacak.
Neden Ansible?
- Idempotans (Tekrarlanabilirlik): Ansible, bir görevi birden fazla kez çalıştırsanız bile sistemin aynı durumda kalmasını sağlar. Bu, yapılandırma hatalarını azaltır.
- Agent-less (Ajan Olmayan): Hedef sunucularda herhangi bir özel yazılım (ajan) kurulmasına gerek yoktur. Sadece SSH ve Python yeterlidir.
- Basit ve Okunabilir: YAML tabanlı sözdizimi sayesinde öğrenmesi ve kullanması kolaydır.
- Modüler ve Genişletilebilir: Rol ve görev yapısı sayesinde kod parçacıkları yeniden kullanılabilir ve kolayca genişletilebilir.
- Çoklu Uygulama Desteği: Değişken yönetimi ve rol yapısı sayesinde farklı uygulamaların farklı gereksinimleri tek bir proje içinde yönetilebilir.
Ön Gereksinimler ve Ortam Kurulumu
Başlamadan önce, Ansible kontrol makinenizde ve hedef sunucunuzda bazı temel kurulumları yapmanız gerekmektedir.
1. Ansible Kontrol Makinesi Kurulumu
Ansible’ı çalıştıracağınız makine (genellikle kendi geliştirme makineniz veya bir CI/CD sunucusu) kontrol makinesi olacaktır. Bu makinede Python ve Ansible yüklü olmalıdır.
# Python 3 ve pip kurulumu (eğer yüklü değilse)
sudo apt update
sudo apt install python3 python3-pip
Ansible kurulumu
pip3 install ansible
Ansible versiyonunu kontrol edin
ansible --version
2. Hedef Sunucu (Ubuntu 14.04) Hazırlığı
Hedef sunucu (Ubuntu 14.04) üzerinde SSH erişimine ve sudo yetkisine sahip bir kullanıcıya ihtiyacınız var. Ayrıca, Ansible’ın çalışması için Python’un yüklü olması gerekir. Ubuntu 14.04’te Python 2.7 genellikle öntanımlı olarak gelir, bu da Ansible için yeterlidir. Ancak, Python 3’ü de kurmak iyi bir pratiktir.
# Hedef sunucuya SSH ile bağlanın ve Python'u kontrol edin
ssh your_user@your_server_ip
python --version # Python 2.7.x olmalı
sudo apt-get update
sudo apt-get install -y python-apt # Ansible için gerekli olabilir
exit
3. SSH Anahtarları ile Parolasız Erişim
Ansible’ın sorunsuz çalışması için kontrol makinenizden hedef sunucuya parolasız SSH erişimi kurmanız şarttır. Eğer yoksa, bir SSH anahtar çifti oluşturun ve genel anahtarınızı hedef sunucuya kopyalayın.
# Kontrol makinesinde
ssh-keygen -t rsa -b 4096 # Eğer anahtarınız yoksa
ssh-copy-id your_user@your_server_ip
Ansible Proje Yapısı ve Envanter Yönetimi
Birden fazla uygulama dağıtırken, iyi organize edilmiş bir Ansible proje yapısı ve değişken yönetimi hayati önem taşır.
1. Proje Dizini Oluşturma
Tüm Ansible dosyalarınızı içeren bir ana dizin oluşturun:
mkdir ansible-php-apps
cd ansible-php-apps
2. Envanter Dosyası (inventory.ini)
Hedef sunucularınızı ve gruplarınızı tanımladığınız dosyadır. Birden fazla sunucuya dağıtım yapacaksanız, her sunucuyu buraya ekleyebilirsiniz. Bu rehberde tek bir sunucuya odaklanıyoruz.
# inventory.ini
[webservers]
your_server_ip ansible_user=your_user ansible_ssh_private_key_file=~/.ssh/id_rsa
your_server_ip yerine sunucunuzun IP adresini veya alan adını, your_user yerine SSH kullanıcı adınızı ve ansible_ssh_private_key_file yerine özel anahtarınızın yolunu yazın.
3. Ana Playbook (site.yml veya playbook.yml)
Tüm rolleri ve görevleri bir araya getiren ana Ansible oyun kitabınızdır.
# playbook.yml
---
- name: Multiple PHP Applications Deployment
hosts: webservers
become: yes # Görevleri sudo yetkisiyle çalıştır
roles:
- common
- apache
- php
- mysql
- app_deploy # Bu rol uygulamaya özel dağıtımı yönetecek
4. Değişken Yönetimi (group_vars ve host_vars)
Bu, birden fazla uygulama dağıtımının kalbidir. Uygulamaya özel ayarları (veritabanı adı, Git deposu, alan adı vb.) bu dosyalarda tanımlayacağız.
group_vars/all.yml
Tüm sunucular için geçerli genel değişkenler.
# group_vars/all.yml
---
Genel sistem ayarları
system_packages:
- vim
- git
- curl
- unzip
Apache ayarları
apache_port: 80
apache_modules:
- rewrite
- php5 # Ubuntu 14.04 için mod_php5
PHP ayarları (Ubuntu 14.04 için PHP 5.x)
php_version: "5.5" # Veya 5.6
php_packages:
- php5
- php5-mysql
- php5-cli
- libapache2-mod-php5
MySQL root şifresi (ilk kurulumda ayarlanacak)
mysql_root_password: "your_mysql_root_password"
Uygulama listesi - Burası birden fazla uygulamayı tanımladığımız yer!
applications:
- name: my_first_app
domain: firstapp.example.com
repo: "https://github.com/your-org/my_first_app.git"
db_name: first_app_db
db_user: first_app_user
db_password: "secure_password_for_app1"
doc_root: /var/www/html/my_first_app/public # Uygulamanın public dizini
- name: my_second_app
domain: secondapp.example.com
repo: "https://github.com/your-org/my_second_app.git"
db_name: second_app_db
db_user: second_app_user
db_password: "another_secure_password_for_app2"
doc_root: /var/www/html/my_second_app/web # Uygulamanın public dizini
applications listesi, dağıtılacak her bir PHP uygulamasını tanımlar. Her uygulama için benzersiz ad, alan adı, Git deposu, veritabanı bilgileri ve doküman kök dizini belirtilmiştir. Bu listeyi genişleterek istediğiniz kadar uygulama ekleyebilirsiniz.
Ansible Rollerinin Oluşturulması ve Uygulama Dağıtımı
Şimdi, ana playbook’umuzda belirtilen rolleri oluşturalım. Her rol, belirli bir hizmetin veya görevin kurulumunu ve yapılandırmasını yönetecek.
1. common Rolü: Temel Sistem Ayarları
Bu rol, sunucunun temel paketlerini kurar ve güvenlik duvarını yapılandırır.
mkdir -p roles/common/tasks
# roles/common/tasks/main.yml
---
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Install common packages
apt:
name: "{{ item }}"
state: present
loop: "{{ system_packages }}"
- name: Configure UFW firewall
community.general.ufw:
rule: allow
port: "{{ apache_port }}"
proto: tcp
- name: Enable UFW firewall
community.general.ufw:
state: enabled
policy: deny
2. apache Rolü: Web Sunucusu Kurulumu
Apache2’yi kurar, gerekli modülleri etkinleştirir ve uygulamalar için sanal ana bilgisayar yapılandırmasını yönetir.
mkdir -p roles/apache/{tasks,templates}
# roles/apache/tasks/main.yml
---
- name: Install Apache2
apt:
name: apache2
state: present
- name: Enable Apache modules
apache2_module:
state: present
name: "{{ item }}"
loop: "{{ apache_modules }}"
notify: Restart apache
- name: Ensure Apache is running and enabled
service:
name: apache2
state: started
enabled: yes
- name: Remove default Apache virtual host
file:
path: /etc/apache2/sites-enabled/000-default.conf
state: absent
notify: Restart apache
Uygulamaya özel sanal ana bilgisayarlar app_deploy rolünde oluşturulacak
# roles/apache/handlers/main.yml
---
- name: Restart apache
service:
name: apache2
state: restarted
3. php Rolü: PHP Kurulumu
PHP 5.x ve gerekli eklentileri yükler.
mkdir -p roles/php/tasks
# roles/php/tasks/main.yml
---
- name: Install PHP packages for Apache (Ubuntu 14.04)
apt:
name: "{{ item }}"
state: present
loop: "{{ php_packages }}"
notify: Restart apache
- name: Configure PHP settings (optional, example: memory_limit)
lineinfile:
path: /etc/php5/apache2/php.ini
regexp: '^memory_limit ='
line: 'memory_limit = 256M'
state: present
notify: Restart apache
4. mysql Rolü: Veritabanı Sunucusu ve Uygulama Veritabanları
MySQL sunucusunu kurar ve her uygulama için ayrı veritabanı ve kullanıcı oluşturur.
mkdir -p roles/mysql/tasks
# roles/mysql/tasks/main.yml
---
- name: Install MySQL server
apt:
name: mysql-server
state: present
- name: Set MySQL root password
mysql_user:
name: root
password: "{{ mysql_root_password }}"
host: "{{ item }}"
login_user: root
login_password: "{{ mysql_root_password }}" # Eğer ilk kurulum ise bu satır olmayacak, sonraki çalıştırmalar için gerekli.
check_implicit_admin: yes # Bu, ilk kurulumda root şifresi ayarlanırken yardımcı olur.
loop:
- localhost
- 127.0.0.1
- ::1
- name: Create MySQL databases for applications
mysql_db:
name: "{{ item.db_name }}"
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
loop: "{{ applications }}"
- name: Create MySQL users and grant privileges for applications
mysql_user:
name: "{{ item.db_user }}"
password: "{{ item.db_password }}"
host: "localhost"
priv: "{{ item.db_name }}.*:ALL"
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
loop: "{{ applications }}"
5. app_deploy Rolü: Uygulamaya Özel Dağıtım
Bu rol, group_vars/all.yml dosyasındaki applications listesini kullanarak her bir PHP uygulamasını dağıtır. Bu, çoklu uygulama dağıtımının anahtar noktasıdır.
mkdir -p roles/app_deploy/{tasks,templates}
# roles/app_deploy/tasks/main.yml
---
- name: Deploy each PHP application
loop: "{{ applications }}"
loop_control:
loop_var: current_app
block:
- name: Ensure application directory exists for {{ current_app.name }}
file:
path: "/var/www/html/{{ current_app.name }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Clone or update Git repository for {{ current_app.name }}
git:
repo: "{{ current_app.repo }}"
dest: "/var/www/html/{{ current_app.name }}"
version: master # Veya belirli bir branch/tag
force: yes # Gerekirse değişiklikleri üzerine yazar
# Sadece ilk dağıtımda veya repo güncellendiğinde çalıştırılabilir
# register: git_result
- name: Ensure correct permissions for {{ current_app.name }}
file:
path: "/var/www/html/{{ current_app.name }}"
state: directory
recurse: yes
owner: www-data
group: www-data
mode: '0755'
- name: Copy Apache virtual host config for {{ current_app.name }}
template:
src: vhost.conf.j2
dest: "/etc/apache2/sites-available/{{ current_app.name }}.conf"
notify: Restart apache
- name: Enable Apache virtual host for {{ current_app.name }}
apache2_module:
state: present
name: "{{ current_app.name }}.conf"
notify: Restart apache
- name: (Optional) Install Composer dependencies for {{ current_app.name }}
community.general.composer:
command: install
working_dir: "/var/www/html/{{ current_app.name }}"
args:
chdir: "/var/www/html/{{ current_app.name }}"
when: "'composer.json' in (ansible_facts.fs_files | default([]) | map(attribute='path') | list)" # Basit bir kontrol
# Bu kontrol Ubuntu 14.04'te ansible_facts.fs_files olmayabilir, daha basit bir stat modülü kullanılabilir.
# Alternatif olarak, stat modülü ile composer.json dosyasının varlığını kontrol edebilirsiniz.
# - name: Check if composer.json exists
# stat:
# path: "/var/www/html/{{ current_app.name }}/composer.json"
# register: composer_json_stat
# - name: Install Composer dependencies if composer.json exists
# command: composer install
# args:
# chdir: "/var/www/html/{{ current_app.name }}"
# when: composer_json_stat.stat.exists
Bu roldeki loop: "{{ applications }}" satırı, group_vars/all.yml dosyasındaki her bir uygulama tanımı için aşağıdaki görev bloğunu çalıştırır. current_app değişkeni, döngünün mevcut uygulamasının bilgilerini içerir.
# roles/app_deploy/templates/vhost.conf.j2
ServerAdmin webmaster@localhost
ServerName {{ current_app.domain }}
DocumentRoot {{ current_app.doc_root }}
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
ErrorLog ${APACHE_LOG_DIR}}/{{ current_app.name }}-error.log
CustomLog ${APACHE_LOG_DIR}}/{{ current_app.name }}-access.log combined
Ansible Playbook’unu Çalıştırma ve Doğrulama
Tüm rolleri ve yapılandırmaları oluşturduktan sonra, Ansible playbook’unu çalıştırmaya hazırsınız. Ana proje dizininizde olduğunuzdan emin olun (ansible-php-apps).
1. Playbook’u Çalıştırma
ansible-playbook -i inventory.ini playbook.yml
Bu komut, inventory.ini dosyasındaki sunucular üzerinde playbook.yml dosyasında tanımlanan tüm rolleri çalıştıracaktır. İlk çalıştırmada birçok değişiklik (paket kurulumu, yapılandırma) göreceksiniz. Sonraki çalıştırmalarda, sistem zaten istenen durumda olduğu için “changed” yerine “ok” veya “skipped” görevler göreceksiniz.
2. Dağıtımı Doğrulama
Playbook başarıyla tamamlandıktan sonra, uygulamalarınızın düzgün çalıştığını doğrulamak için aşağıdaki adımları izleyin:
- SSH ile Sunucuya Bağlanın: Uygulama dizinlerinin ve yapılandırma dosyalarının varlığını kontrol edin.
ssh your_user@your_server_ip ls -l /var/www/html/my_first_app ls -l /etc/apache2/sites-available/my_first_app.conf - Veritabanlarını Kontrol Edin: MySQL’e bağlanarak veritabanlarının ve kullanıcıların oluşturulduğunu doğrulayın.
mysql -u root -ppassword: your_mysql_root_password
SHOW DATABASES; USE first_app_db; SHOW TABLES; # Eğer uygulamanızın veritabanında tablolar varsa - Tarayıcıdan Uygulamalara Erişim:
/etc/hostsdosyanıza veya DNS sağlayıcınıza sunucunuzun IP adresini ve tanımladığınız alan adlarını ekleyerek tarayıcınızdan uygulamalara erişmeyi deneyin.# Kontrol makinenizde /etc/hosts dosyasına ekleyin (Linux/macOS)veya C:\Windows\System32\drivers\etc\hosts (Windows)
your_server_ip firstapp.example.com secondapp.example.comDaha sonra tarayıcınızda
http://firstapp.example.comvehttp://secondapp.example.comadreslerini ziyaret edin.
Sonuç ve Sıkça Sorulan Sorular (SSS)
Bu rehberde, Ansible’ın rol tabanlı yapısını ve değişken yönetimini kullanarak Ubuntu 14.04 sunucusuna birden fazla PHP uygulamasını nasıl dağıtacağınızı öğrendiniz. Bu yaklaşım, dağıtım süreçlerinizi otomatikleştirmenize, tutarlılığı sağlamanıza ve zaman içinde bakımı kolaylaştırmanıza olanak tanır. Uygulama sayınız arttıkça veya sunucu altyapınız genişledikçe bu otomasyonun faydaları daha da belirginleşecektir.
Sıkça Sorulan Sorular (SSS)
S1: Ubuntu 14.04 yerine daha yeni bir Ubuntu sürümünde (örn. 20.04, 22.04) bu rehberi kullanabilir miyim?
C1: Evet, temel Ansible prensipleri aynı kalacaktır. Ancak, paket isimleri ve PHP versiyonları değişecektir. Örneğin, php5 yerine php, php5-mysql yerine php-mysql veya php-fpm kullanmanız gerekebilir. Apache modülleri için de mod_php5 yerine mod_php veya PHP-FPM ile çalışmak için farklı yapılandırmalar gerekebilir.
S2: Apache yerine Nginx kullanmak istersem ne yapmalıyım?
C2: apache rolünü tamamen kaldırıp yerine bir nginx rolü oluşturmanız gerekir. Bu rol Nginx’i kurar, PHP-FPM’i yapılandırır ve her uygulama için Nginx sunucu bloğu (virtual host eşdeğeri) şablonları oluşturur. php rolünüzün de PHP-FPM’i kurduğundan emin olmanız gerekir.
S3: Veritabanı sunucusu ayrı bir makinede olursa ne yapmalıyım?
C3: inventory.ini dosyanızda ayrı bir [dbservers] grubu tanımlayabilir ve mysql rolünü sadece bu gruba uygulayabilirsiniz. Uygulamaların veritabanı bağlantı bilgilerini güncellemeyi unutmayın (localhost yerine veritabanı sunucusunun IP adresi veya alan adı).
S4: Farklı uygulamalar için farklı PHP versiyonları kullanabilir miyim?
C4: Bu daha karmaşık bir senaryodur. Genellikle PHP-FPM havuzlarını kullanarak ve her uygulama için farklı bir PHP-FPM havuzu yapılandırarak (örneğin, PHP 7.4 için bir havuz, PHP 8.1 için başka bir havuz) bunu başarabilirsiniz. Apache veya Nginx sanal ana bilgisayar yapılandırmalarını da buna göre ayarlamanız gerekir. Bu rehberin kapsamını aşan ileri düzey bir konudur.
S5: Dağıtım sonrası otomatik testler veya önbellek temizleme gibi görevler ekleyebilir miyim?
C5: Kesinlikle! app_deploy rolünüzdeki her uygulama bloğunun sonuna post_tasks veya ek görevler ekleyebilirsiniz. Örneğin, Laravel uygulamaları için php artisan migrate veya php artisan cache:clear gibi komutları çalıştırabilirsiniz.