Docker Compose Rehberi: Çok Konteynerli Uygulama Yönetimi
Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.
Ansible kurulumu, inventory dosyası, playbook yazımı, rol yapısı, değişkenler, şifreli vault, ad-hoc komutlar ve sunucu yapılandırma otomasyonu. Adım adım rehber.
Ansible, sunucu yapılandırmasını, uygulama dağıtımını ve görev otomasyonunu kod olarak yönetmenizi sağlayan açık kaynaklı bir araçtır. Agentsız mimarisi sayesinde hedef sunuculara yalnızca SSH ile bağlanır.
Ansible'ın temel özellikleri:
Ansible, kontrol düğümünden (control node) hedef sunuculara SSH üzerinden bağlanır. Windows sunucular için WinRM kullanılır.
# PPA deposunu ekle
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
# Sürümü kontrol et
ansible --version
# EPEL deposunu ekle
sudo dnf install epel-release -y
sudo dnf install ansible -y
# Alternatif: pip ile kur
pip3 install ansible
# Python sanal ortamı oluştur
python3 -m venv ansible-env
source ansible-env/bin/activate
# Ansible ve ek araçları kur
pip install ansible ansible-lint
# Sürümü kontrol et
ansible --version
Inventory, Ansible'ın yöneteceği sunucuları tanımlar:
# /etc/ansible/hosts veya özel inventory dosyası
# Tekil sunucu
web1.example.com
# Grup tanımlama
[webservers]
web1.example.com
web2.example.com ansible_port=2222
192.168.1.10 ansible_user=ubuntu
[databases]
db1.example.com
db2.example.com
# Grup değişkenleri
[webservers:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3
# Üst grup
[production:children]
webservers
databases
# inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
ansible_port: 22
web2.example.com:
ansible_port: 2222
vars:
ansible_user: deploy
http_port: 80
databases:
hosts:
db1.example.com:
db2.example.com:
vars:
ansible_user: dbadmin
db_port: 5432
staging:
hosts:
staging.example.com:
ansible_host: 192.168.1.50
Hızlı görevler için playbook yazmadan komut çalıştırın:
# Ping testi
ansible all -m ping
ansible webservers -m ping -i inventory.yml
# Komut çalıştır
ansible all -m command -a "uptime"
ansible webservers -m shell -a "df -h"
# Dosya kopyala
ansible webservers -m copy -a "src=/local/file dest=/remote/path"
# Paket kur
ansible webservers -m apt -a "name=nginx state=present" --become
# Servis yönet
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become
# Dosya oluştur/sil
ansible all -m file -a "path=/tmp/test state=touch"
ansible all -m file -a "path=/tmp/test state=absent"
# Fact topla
ansible web1.example.com -m setup
ansible all -m setup -a "filter=ansible_os_family"
# site.yml
---
- name: Web sunucularını yapılandır
hosts: webservers
become: yes # sudo kullan
vars:
http_port: 80
max_clients: 200
tasks:
- name: Nginx kur
apt:
name: nginx
state: present
update_cache: yes
- name: Nginx yapılandırmasını kopyala
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Nginx yeniden başlat
- name: Nginx servisini başlat
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Nginx yeniden başlat
service:
name: nginx
state: restarted
# Koşullu görevler
- name: Ubuntu'da paket kur
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "Debian"
- name: RHEL'de paket kur
dnf:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "RedHat"
# Döngü ile kullanıcı oluştur
- name: Kullanıcıları oluştur
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
loop:
- { name: 'ali', groups: 'sudo' }
- { name: 'veli', groups: 'www-data' }
# Kayıt ve koşul
- name: Nginx sürümünü kontrol et
command: nginx -v
register: nginx_version
ignore_errors: yes
- name: Nginx kurulu değilse kur
apt:
name: nginx
state: present
when: nginx_version.rc != 0
# group_vars/webservers.yml
http_port: 80
https_port: 443
app_user: www-data
app_dir: /var/www/html
# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
server_name: web1.example.com
# Playbook içinde değişken kullanımı
- name: Uygulama dizini oluştur
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
# Facts kullanımı
- name: Sistem bilgilerini göster
debug:
msg: |
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPU: {{ ansible_processor_vcpus }} çekirdek
RAM: {{ ansible_memtotal_mb }} MB
IP: {{ ansible_default_ipv4.address }}
Hassas verileri şifrelemek için:
# Şifreli dosya oluştur
ansible-vault create secrets.yml
# Mevcut dosyayı şifrele
ansible-vault encrypt vars/passwords.yml
# Şifreli dosyayı düzenle
ansible-vault edit secrets.yml
# Şifreyi görüntüle
ansible-vault view secrets.yml
# Şifrelemeyi kaldır
ansible-vault decrypt vars/passwords.yml
# Şifreyi değiştir
ansible-vault rekey secrets.yml
# Vault ile playbook çalıştır
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
# secrets.yml (şifreli içerik)
db_password: "gizli_veritabani_sifresi"
api_key: "gizli_api_anahtari"
ssl_cert_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
# Rol oluştur
ansible-galaxy init roles/nginx
# Rol dizin yapısı
roles/nginx/
├── defaults/
│ └── main.yml # Varsayılan değişkenler
├── files/
│ └── nginx.conf # Statik dosyalar
├── handlers/
│ └── main.yml # Handler'lar
├── meta/
│ └── main.yml # Rol meta bilgileri
├── tasks/
│ └── main.yml # Ana görevler
├── templates/
│ └── vhost.conf.j2 # Jinja2 şablonları
└── vars/
└── main.yml # Değişkenler
# roles/nginx/tasks/main.yml
---
- name: Nginx kur
package:
name: nginx
state: present
- name: Nginx yapılandır
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ site_name }}
notify: Nginx yeniden yükle
- name: Siteyi etkinleştir
file:
src: /etc/nginx/sites-available/{{ site_name }}
dest: /etc/nginx/sites-enabled/{{ site_name }}
state: link
notify: Nginx yeniden yükle
---
- name: Nginx web sunucusu kurulumu
hosts: webservers
become: yes
vars:
domain: example.com
web_root: /var/www/{{ domain }}
tasks:
- name: Nginx kur
apt:
name: nginx
state: present
update_cache: yes
- name: Web dizini oluştur
file:
path: "{{ web_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Örnek index.html oluştur
copy:
content: "<h1>Merhaba {{ inventory_hostname }}</h1>"
dest: "{{ web_root }}/index.html"
owner: www-data
- name: Virtual host yapılandır
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: Nginx yeniden yükle
- name: Virtual host etkinleştir
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: Nginx yeniden yükle
- name: Default site devre dışı bırak
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Nginx yeniden yükle
- name: UFW Nginx izni
ufw:
rule: allow
name: 'Nginx Full'
handlers:
- name: Nginx yeniden yükle
service:
name: nginx
state: reloaded
---
- name: Kullanıcı yönetimi
hosts: all
become: yes
vars_files:
- vars/users.yml
tasks:
- name: Sudo grubunu oluştur
group:
name: sudo
state: present
- name: Kullanıcıları oluştur
user:
name: "{{ item.username }}"
comment: "{{ item.full_name }}"
groups: "{{ item.groups | join(',') }}"
shell: /bin/bash
create_home: yes
state: present
loop: "{{ users }}"
- name: SSH public key ekle
authorized_key:
user: "{{ item.username }}"
key: "{{ item.ssh_key }}"
state: present
loop: "{{ users }}"
when: item.ssh_key is defined
- name: Sudo yetkisi ver
copy:
content: "{{ item.username }} ALL=(ALL) NOPASSWD:ALL"
dest: /etc/sudoers.d/{{ item.username }}
mode: '0440'
loop: "{{ users }}"
when: item.sudo | default(false)
# Temel çalıştırma
ansible-playbook site.yml
# Belirli inventory ile
ansible-playbook -i inventory.yml site.yml
# Belirli host veya grup
ansible-playbook site.yml --limit webservers
ansible-playbook site.yml --limit web1.example.com
# Dry-run (değişiklik yapmadan kontrol)
ansible-playbook site.yml --check
# Verbose mod
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv
# Belirli tag'leri çalıştır
ansible-playbook site.yml --tags "nginx,ssl"
ansible-playbook site.yml --skip-tags "debug"
# Ekstra değişken
ansible-playbook site.yml -e "env=production version=1.5"
Ansible, sunucu otomasyonunu kod olarak yönetmenin en erişilebilir yollarından biridir. Agentsız mimarisi, geniş modül kütüphanesi ve YAML tabanlı yapısı ile hem küçük hem de büyük ölçekli altyapıları kolayca yönetebilirsiniz. Vault ile hassas verileri güvende tutarken, roller ile yeniden kullanılabilir yapılandırmalar oluşturabilirsiniz.
Ansible agentsız çalışır (sadece SSH gerekir), Puppet ve Chef ise hedef sunuculara agent kurulumu gerektirir. Ansible YAML tabanlı ve öğrenmesi daha kolaydır. Puppet ve Chef daha güçlü durum yönetimi sunar ancak kurulumu ve öğrenmesi daha karmaşıktır. Küçük-orta ölçekli altyapılar için Ansible genellikle tercih edilir.
Idempotency, aynı işlemi birden fazla kez çalıştırmanın her seferinde aynı sonucu vermesi anlamına gelir. Ansible modülleri idempotent tasarlanmıştır: nginx zaten kuruluysa tekrar kurmaz, dosya zaten doğruysa değiştirmez. Bu sayede playbook'ları güvenle tekrar çalıştırabilirsiniz.
Vault şifresi unutulursa şifreli dosyalar kurtarılamaz. Bu nedenle vault şifresini güvenli bir parola yöneticisinde (1Password, Bitwarden vb.) saklamanız kritik önem taşır. Üretim ortamlarında vault şifresini bir dosyaya yazıp (--vault-password-file) güvenli bir yerde saklamak önerilir.
Ansible Galaxy, topluluk tarafından oluşturulan rollerin ve koleksiyonların paylaşıldığı resmi platformdur (galaxy.ansible.com). 'ansible-galaxy install geerlingguy.nginx' gibi komutlarla hazır rolleri indirebilirsiniz. Bu sayede sıfırdan yazmak yerine test edilmiş rolleri kullanabilirsiniz.
ansible.cfg dosyasında 'forks' değerini artırın (varsayılan 5, 20-50 arası önerilir). 'pipelining = True' ile SSH bağlantı sayısını azaltın. 'strategy: free' ile bağımsız host'ların paralel çalışmasını sağlayın. Büyük inventory'lerde 'serial' ile batch boyutunu kontrol edin.
Evet, Ansible Windows sunucularını WinRM (Windows Remote Management) protokolü üzerinden yönetebilir. 'ansible_connection: winrm' ve 'ansible_winrm_transport: ntlm' ayarları gereklidir. Windows modülleri 'win_' önekiyle başlar: win_package, win_service, win_file gibi.
Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.
GitHub Actions ile CI/CD pipeline oluşturma, Docker build ve push, SSH ile sunucuya deployment, test otomasyonu, secrets yönetimi ve workflow optimizasyonu.
Caddy web server kurulumu, Caddyfile yapılandırması, otomatik Let's Encrypt SSL, reverse proxy, static site hosting, PHP-FPM entegrasyonu ve performans ayarları.