feat: prepare-new-server playbook + role struktura

playbook prepare-new-server.yml:
- update systemu
- deploy user (UID 1000, heslo zamknuto)
- SSH klic pro deploy uzivatele
- adresarova struktura (/home/deploy/{docker,scripts,backups,logs,...})
- Docker Engine + Compose plugin (bez sudo)
- UFW firewall (22, 80, 443)
- fail2ban
- overeni docker bez sudo

Role (kazda v samostatnem adresari):
- common: update, base packages, timezone
- deploy-user: vytvoreni usera UID 1000
- ssh-keys: authorized_keys deployment
- firewall: UFW konfigurace
- docker: Docker Engine + Compose + daemon.json
- directories: /home/deploy/{docker/<sluzba>,backups,scripts,logs}

Pouziti:
  ansible-playbook -i inventory.yml playbooks/prepare-new-server.yml
This commit is contained in:
2026-08-01 20:02:19 +02:00
parent da9003aef8
commit ec2f1d639c
16 changed files with 638 additions and 15 deletions
+30
View File
@@ -0,0 +1,30 @@
---
# Společné proměnné pro common roli
deploy_user: deploy
deploy_uid: 1000
deploy_group: docker
deploy_groups:
- docker
- sudo
- adm
- systemd-journal
timezone: Europe/Prague
# Balíky co se instalují vždy
base_packages:
- curl
- wget
- git
- vim
- htop
- ca-certificates
- gnupg
- lsb-release
- apt-transport-https
- bash-completion
- software-properties-common
- unzip
- zip
- rsync
- net-tools
+26
View File
@@ -0,0 +1,26 @@
---
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Upgrade vsech baliku
ansible.builtin.apt:
upgrade: dist
update_cache: true
autoremove: true
- name: Instalace zakladnich baliku
ansible.builtin.apt:
name: "{{ base_packages }}"
state: present
update_cache: true
- name: Nastav timezone
community.general.timezone:
name: "{{ timezone }}"
- name: Over ze hostname je spravne
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
when: inventory_hostname is defined
+12
View File
@@ -0,0 +1,12 @@
---
# Proměnné pro deploy-user roli
deploy_user: deploy
deploy_uid: 1000
deploy_home: "/home/{{ deploy_user }}"
deploy_groups:
- docker
- sudo
- adm
- systemd-journal
deploy_shell: /bin/bash
deploy_password_locked: true # heslo zamknuto, jen SSH klic
+41
View File
@@ -0,0 +1,41 @@
---
- name: Vytvor skupiny pro deploy uzivatele
ansible.builtin.group:
name: "{{ item }}"
state: present
loop: "{{ deploy_groups }}"
- name: Vytvor deploy uzivatele (UID {{ deploy_uid }})
ansible.builtin.user:
name: "{{ deploy_user }}"
uid: "{{ deploy_uid }}"
group: "{{ deploy_groups[0] }}"
groups: "{{ deploy_groups | join(',') }}"
shell: "{{ deploy_shell }}"
create_home: true
home: "{{ deploy_home }}"
password: "!"
update_password: always
append: true
- name: Uzamkni heslo deploy uzivatele
ansible.builtin.command: passwd -l {{ deploy_user }}
changed_when: false
- name: Vytvor .ssh adresar pro deploy uzivatele
ansible.builtin.file:
path: "{{ deploy_home }}/.ssh"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0700"
- name: Vytvor authorized_keys soubor
ansible.builtin.file:
path: "{{ deploy_home }}/.ssh/authorized_keys"
state: touch
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0600"
modification_time: preserve
access_time: preserve
+42
View File
@@ -0,0 +1,42 @@
---
# Proměnné pro directories roli
deploy_user: deploy
deploy_home: "/home/{{ deploy_user }}"
# Zakladni adresarova struktura
base_directories:
- path: "{{ deploy_home }}/docker"
description: "Docker sluzby (kazda v samostatne slozce)"
mode: "0755"
- path: "{{ deploy_home }}/docker-services-repo"
description: "Git repo s docker-compose sablonami (klonovane)"
mode: "0755"
- path: "{{ deploy_home }}/backups"
description: "Lokalni zalohy Docker dat (pred rsync na NAS)"
mode: "0750"
- path: "{{ deploy_home }}/scripts"
description: "Vlastni bash skripty"
mode: "0755"
- path: "{{ deploy_home }}/logs"
description: "Logy serveru (mimo system log)"
mode: "0755"
- path: "{{ deploy_home }}/.local/bin"
description: "Uzivatelske binarky (Hermes atd.)"
mode: "0755"
# Podadresare pro Docker stack
docker_subdirs:
- "{{ deploy_home }}/docker/portainer"
- "{{ deploy_home }}/docker/nginx-proxy-manager"
- "{{ deploy_home }}/docker/vaultwarden"
- "{{ deploy_home }}/docker/gitea"
- "{{ deploy_home }}/docker/jotty"
- "{{ deploy_home }}/docker/nextcloud"
- "{{ deploy_home }}/docker/rustdesk"
- "{{ deploy_home }}/docker/audiobookshelf"
- "{{ deploy_home }}/docker/calibre-web"
- "{{ deploy_home }}/docker/plex"
- "{{ deploy_home }}/docker/erugo"
- "{{ deploy_home }}/docker/jswiki"
- "{{ deploy_home }}/docker/speedtest"
- "{{ deploy_home }}/docker/watchtower"
+27
View File
@@ -0,0 +1,27 @@
---
- name: Vytvor zakladni adresare
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "{{ item.mode }}"
loop: "{{ base_directories }}"
- name: Vytvor podadresare pro Docker sluzby
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0755"
loop: "{{ docker_subdirs }}"
- name: Vytvor .gitkeep v prazdnych docker podadresarich
ansible.builtin.file:
path: "{{ item }}/.gitkeep"
state: touch
owner: "{{ deploy_user }}"
group: "{{ deploy_user }}"
mode: "0644"
loop: "{{ docker_subdirs }}"
+14
View File
@@ -0,0 +1,14 @@
---
# Proměnné pro docker roli
deploy_user: deploy
docker_compose_version: "v2.27.0"
# Docker daemon nastaveni
docker_daemon_config:
log-driver: json-file
log-opts:
max-size: "10m"
max-file: "3"
storage-driver: overlay2
live-restore: true
userland-proxy: false
+5
View File
@@ -0,0 +1,5 @@
---
- name: Restart docker
ansible.builtin.systemd:
name: docker
state: restarted
+89
View File
@@ -0,0 +1,89 @@
---
- name: Nainstaluj prerekvizity pro Docker
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg
state: present
update_cache: true
- name: Vytvor adresar pro Docker GPG klic
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
- name: Stahn Docker GPG klic
ansible.builtin.get_url:
url: https://download.docker.com/linux/ubuntu/gpg
dest: /etc/apt/keyrings/docker.asc
mode: "0644"
force: true
- name: Pridej Docker repo
ansible.builtin.apt_repository:
repo: >-
deb [arch={{ ansible_architecture | replace('x86_64', 'amd64') | replace('aarch64', 'arm64') }}
signed-by=/etc/apt/keyrings/docker.asc]
https://download.docker.com/linux/ubuntu
{{ ansible_distribution_release }} stable
filename: docker
state: present
update_cache: true
- name: Nainstaluj Docker Engine a Compose plugin
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
state: present
update_cache: true
- name: Over ze Docker bezi
ansible.builtin.systemd:
name: docker
state: started
enabled: true
- name: Nastav docker daemon.json
ansible.builtin.copy:
content: "{{ docker_daemon_config | to_nice_json }}"
dest: /etc/docker/daemon.json
owner: root
group: root
mode: "0644"
notify: Restart docker
- name: Pridej deploy uzivatele do docker group (docker bez sudo)
ansible.builtin.user:
name: "{{ deploy_user }}"
groups: docker
append: true
- name: Over docker verze
ansible.builtin.command: docker --version
register: docker_version_output
changed_when: false
- ansible.builtin.debug:
msg: "Docker nainstalovan: {{ docker_version_output.stdout }}"
- name: Over docker compose verze
ansible.builtin.command: docker compose version
register: docker_compose_output
changed_when: false
- ansible.builtin.debug:
msg: "Docker Compose: {{ docker_compose_output.stdout }}"
- name: Test docker bez sudo
ansible.builtin.command: docker ps
become: true
become_user: "{{ deploy_user }}"
changed_when: false
register: docker_ps_test
failed_when: docker_ps_test.rc != 0
- ansible.builtin.debug:
msg: "Docker bez sudo funguje pro {{ deploy_user }}"
+8
View File
@@ -0,0 +1,8 @@
---
# Proměnné pro firewall roli
ssh_port: 22
# Dalsi porty co chces povolit (pro servery)
allowed_ports:
- { port: 80, proto: tcp, comment: "HTTP" }
- { port: 443, proto: tcp, comment: "HTTPS" }
- { port: "{{ ssh_port }}", proto: tcp, comment: "SSH" }
+32
View File
@@ -0,0 +1,32 @@
---
- name: Nainstaluj UFW
ansible.builtin.apt:
name: ufw
state: present
update_cache: true
- name: Reset UFW na default
community.general.ufw:
state: reset
- name: UFW default - deny incoming
community.general.ufw:
direction: incoming
policy: deny
- name: UFW default - allow outgoing
community.general.ufw:
direction: outgoing
policy: allow
- name: Povol porty pres UFW
community.general.ufw:
rule: allow
port: "{{ item.port }}"
proto: "{{ item.proto }}"
comment: "{{ item.comment }}"
loop: "{{ allowed_ports }}"
- name: Aktivuj UFW
community.general.ufw:
state: enabled
+14
View File
@@ -0,0 +1,14 @@
---
# Proměnné pro ssh-keys roli
deploy_user: deploy
deploy_home: "/home/{{ deploy_user }}"
ssh_key_path: "{{ deploy_home }}/.ssh/authorized_keys"
ssh_key_owner: "{{ deploy_user }}"
ssh_key_group: "{{ deploy_user }}"
ssh_key_mode: "0600"
# Verejne klice pro deploy uzivatele (nastav v inventory.yml)
# deploy_ssh_public_keys:
# - "ssh-ed25519 AAAAC3Nz... hermes@mac"
# - "ssh-rsa AAAAB3... backup@server"
deploy_ssh_public_keys: []
+23
View File
@@ -0,0 +1,23 @@
---
- name: Over ze deploy_ssh_public_keys je nastaveno
ansible.builtin.assert:
that:
- deploy_ssh_public_keys is defined
- deploy_ssh_public_keys | length > 0
fail_msg: "deploy_ssh_public_keys neni nastaven. Pridej ho do group_vars/all.yml nebo inventory."
- name: Nastav authorized_keys pro deploy uzivatele
ansible.posix.authorized_key:
user: "{{ deploy_user }}"
state: present
key: "{{ item }}"
exclusive: false # neprepisuj existujici klice
loop: "{{ deploy_ssh_public_keys }}"
when: deploy_ssh_public_keys | length > 0
- name: Nastav spravna opravneni na authorized_keys
ansible.builtin.file:
path: "{{ ssh_key_path }}"
owner: "{{ ssh_key_owner }}"
group: "{{ ssh_key_group }}"
mode: "{{ ssh_key_mode }}"