Compare commits

...

2 Commits
v3.3 ... main

22 changed files with 842 additions and 54 deletions

Binary file not shown.

12
ansible.cfg Normal file
View File

@ -0,0 +1,12 @@
[defaults]
inventory = inventory/hosts
roles_path = roles
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

View File

@ -1,54 +1,55 @@
---
# Alicante Core V4.1 - Configuración Global
# IPs
core_ip: "10.10.10.104"
dcc_ip: "10.10.10.101"
# Credenciales
core_user: "CORE"
core_email: "ANT1NONAME@DISROOT.ORG"
core_password: "coreALICANTE@2026"
# Rutas
data_root: "/DATA/VOLUMENES"
docker_root: "/opt/services"
# PHP Multiversión
php_versions:
- "8.1"
- "8.2"
- "8.3"
# Timezone
timezone: "Europe/Madrid"
# Contraseñas Maestras (Se usan para configurar las DBs internas de cada stack)
global_db_pass: "RootSecret123"
global_redis_pass: "RedisSecret123"
authentik_secret: "AlicanteAuthSecret2025_ChangeMe"
# Puertos (Mantenidos de V4)
ports:
dolibarr: 8080
nextcloud: 8088
joomla: 8090
teable: 3000
activepieces: 8081
wikijs: 6875
metabase: 3001
gotenberg: 3002
dockge: 5001
leantime: 8085
vaultwarden: 8812
pretix: 8095
ontime: 4000
opensign: 8086
beszel: 8177
webmin: 10000
sysadmin_email: "admin@alicante.local"
global_db_root_pass: "RootSecret123"
global_db_app_pass: "AppSecret123"
global_redis_pass: "RedisSecret123"
authentik_secret: "GenerarStringLargoAleatorio123456"
authentik_pg_pass: "AuthDBSecret123"
pg_version: "16"
# URLs de descarga - VERSIONES MÁS RECIENTES
download_urls:
nextcloud: "https://download.nextcloud.com/server/releases/nextcloud-31.0.0.tar.bz2"
joomla: "https://github.com/joomla/joomla-cms/releases/download/6.0.0/Joomla_6.0.0-Stable-Full_Package.zip"
dolibarr: "https://github.com/Dolibarr/dolibarr/archive/refs/tags/22.0.1.tar.gz"
# ============================================================================
# ALICANTE CORE V3.3 - Credenciales estándar
# ============================================================================
# Usuario estándar CORE
core_user:
username: "CORE"
firstname: "ALICANTE"
lastname: "CORE"
email: "ANT1NONAME@DISROOT.ORG"
password: "coreALICANTE@2026"
# Credenciales de bases de datos
core_db_credentials:
postgres_root_password: "coreALICANTE@2026"
dolibarr_db_name: "dolibarr_db"
dolibarr_db_user: "dolibarr_core"
dolibarr_db_pass: "coreALICANTE@2026"
teable_db_name: "teable_db"
teable_db_user: "teable_core"
teable_db_pass: "coreALICANTE@2026"
activepieces_db_name: "activepieces_db"
activepieces_db_user: "activepieces_core"
activepieces_db_pass: "coreALICANTE@2026"
wikijs_db_name: "wikijs_db"
wikijs_db_user: "wikijs_core"
wikijs_db_pass: "coreALICANTE@2026"
metabase_db_name: "metabase_db"
metabase_db_user: "metabase_core"
metabase_db_pass: "coreALICANTE@2026"
# Dominios (adaptar a tus dominios reales de NPM)
dolibarr_domain: "dolibarr.tudominio.com"
teable_domain: "teable.tudominio.com"
activepieces_domain: "activepieces.tudominio.com"
wikijs_domain: "wiki.tudominio.com"
metabase_domain: "metabase.tudominio.com"
authentik_domain: "auth.tudominio.com"
# Versiones
versions:
nextcloud: "31.0"
joomla: "6.0"
dolibarr: "22.0"

View File

@ -1,5 +0,0 @@
[core]
10.10.10.104 ansible_user=root ansible_connection=ssh
[all:vars]
ansible_python_interpreter=/usr/bin/python3

5
inventory/hosts Normal file
View File

@ -0,0 +1,5 @@
[core]
10.10.10.104 ansible_user=root ansible_ssh_private_key_file=~/.ssh/alicante_key
[dcc]
localhost ansible_connection=local

16
inventory/hosts.yml Normal file
View File

@ -0,0 +1,16 @@
---
all:
children:
alicante:
hosts:
alicante-core:
ansible_host: 10.10.10.104
ansible_user: root
ansible_python_interpreter: /usr/bin/python3
dcc_servers:
hosts:
dcc:
ansible_host: 10.10.10.101
ansible_user: root
ansible_connection: local

32
playbooks/deploy_v4_1.yml Normal file
View File

@ -0,0 +1,32 @@
---
- name: Alicante Core V4 -> V4.1 Actualización
hosts: core
become: yes
vars_files:
- ../group_vars/all.yml
pre_tasks:
- name: Mostrar información de actualización
debug:
msg: "Actualizando CORE {{ core_ip }} a V4.1 - Híbrido LAMP+Docker"
roles:
- base_system
- webmin_lamp
- docker_base
post_tasks:
- name: Resumen de servicios instalados
debug:
msg: |
✅ V4.1 Base instalada:
- Webmin: http://{{ core_ip }}:{{ ports.webmin }}
- PHP: 8.1, 8.2, 8.3 instalados
- MariaDB + PostgreSQL + Redis activos
- Docker + Dockge: http://{{ core_ip }}:{{ ports.dockge }}
⚠️ Nota: Webmin, MariaDB y PostgreSQL ya estaban instalados
Próximos pasos:
- Desplegar apps nativas (Joomla, Dolibarr, Nextcloud)
- Desplegar apps Docker (Teable, Pretix, etc.)

View File

@ -0,0 +1,53 @@
---
- name: Alicante Core V4.1 - Despliegue Completo
hosts: alicante
become: yes
vars_files:
- ../group_vars/all.yml
pre_tasks:
- name: Información del despliegue
debug:
msg: |
🚀 Desplegando Alicante Core V4.1 COMPLETO
📍 Server: {{ core_ip }}
🔧 Apps Nativas: Nextcloud, Joomla, Dolibarr
🐳 Apps Docker: Teable, Wiki.js, Leantime, Vaultwarden, Metabase, Gotenberg, Ontime
roles:
- base_system
- webmin_lamp
- docker_base
- app_nextcloud_native
- app_joomla_native
- app_dolibarr_native
- apps_docker
post_tasks:
- name: Resumen Final
debug:
msg: |
✅ ALICANTE CORE V4.1 DESPLEGADO COMPLETAMENTE
📱 APPS NATIVAS:
- Nextcloud: http://{{ core_ip }}:{{ ports.nextcloud }}
- Joomla: http://{{ core_ip }}:{{ ports.joomla }}
- Dolibarr: http://{{ core_ip }}:{{ ports.dolibarr }}
🐳 APPS DOCKER:
- Teable: http://{{ core_ip }}:{{ ports.teable }}
- Wiki.js: http://{{ core_ip }}:{{ ports.wikijs }}
- Leantime: http://{{ core_ip }}:{{ ports.leantime }}
- Vaultwarden: http://{{ core_ip }}:{{ ports.vaultwarden }}
- Metabase: http://{{ core_ip }}:{{ ports.metabase }}
- Gotenberg: http://{{ core_ip }}:{{ ports.gotenberg }}
- Ontime: http://{{ core_ip }}:{{ ports.ontime }}
- Dockge: http://{{ core_ip }}:{{ ports.dockge }}
🔧 ADMINISTRACIÓN:
- Webmin: http://{{ core_ip }}:{{ ports.webmin }}
📝 CREDENCIALES:
- Usuario: {{ core_user }}
- Email: {{ core_email }}
- Password: {{ core_password }}

View File

@ -0,0 +1,5 @@
---
- name: restart apache2
service:
name: apache2
state: restarted

View File

@ -0,0 +1,72 @@
---
- name: Verificar si Dolibarr ya existe
stat:
path: /var/www/html/dolibarr
register: dolibarr_exists
- name: Crear base de datos MariaDB para Dolibarr
mysql_db:
name: dolibarr
state: present
login_unix_socket: /run/mysqld/mysqld.sock
when: not dolibarr_exists.stat.exists
- name: Crear usuario MariaDB para Dolibarr
mysql_user:
name: dolibarr
password: "{{ core_password }}"
priv: 'dolibarr.*:ALL'
state: present
login_unix_socket: /run/mysqld/mysqld.sock
when: not dolibarr_exists.stat.exists
- name: Descargar Dolibarr 22.0
get_url:
url: "{{ download_urls.dolibarr }}"
dest: /tmp/dolibarr-22.0.tar.gz
when: not dolibarr_exists.stat.exists
- name: Extraer Dolibarr
unarchive:
src: /tmp/dolibarr-22.0.tar.gz
dest: /tmp/
remote_src: yes
when: not dolibarr_exists.stat.exists
- name: Mover Dolibarr a /var/www/html
command: mv /tmp/dolibarr-22.0.1 /var/www/html/dolibarr
args:
creates: /var/www/html/dolibarr
when: not dolibarr_exists.stat.exists
- name: Establecer permisos Dolibarr
file:
path: /var/www/html/dolibarr
owner: www-data
group: www-data
recurse: yes
- name: Crear directorio documentos Dolibarr
file:
path: "{{ data_root }}/dolibarr"
state: directory
owner: www-data
group: www-data
mode: '0750'
- name: Configurar VirtualHost Dolibarr
template:
src: dolibarr.conf.j2
dest: /etc/apache2/sites-available/dolibarr.conf
notify: restart apache2
- name: Habilitar sitio Dolibarr
command: a2ensite dolibarr
args:
creates: /etc/apache2/sites-enabled/dolibarr.conf
notify: restart apache2
- name: Informar si Dolibarr ya existe
debug:
msg: "Dolibarr ya está instalado, saltando descarga"
when: dolibarr_exists.stat.exists

View File

@ -0,0 +1,13 @@
<VirtualHost *:{{ ports.dolibarr }}>
DocumentRoot /var/www/html/dolibarr/htdocs
<Directory /var/www/html/dolibarr/htdocs/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>

View File

@ -0,0 +1,5 @@
---
- name: restart apache2
service:
name: apache2
state: restarted

View File

@ -0,0 +1,76 @@
---
- name: Verificar si Joomla ya existe
stat:
path: /var/www/html/joomla/configuration.php
register: joomla_exists
- name: Crear base de datos MariaDB para Joomla
mysql_db:
name: joomla
state: present
login_unix_socket: /run/mysqld/mysqld.sock
when: not joomla_exists.stat.exists
- name: Crear usuario MariaDB para Joomla
mysql_user:
name: joomla
password: "{{ core_password }}"
priv: 'joomla.*:ALL'
state: present
login_unix_socket: /run/mysqld/mysqld.sock
when: not joomla_exists.stat.exists
- name: Crear directorio Joomla
file:
path: /var/www/html/joomla
state: directory
owner: www-data
group: www-data
- name: Instalar unzip si no existe
apt:
name: unzip
state: present
when: not joomla_exists.stat.exists
- name: Descargar Joomla 6.0 desde GitHub
get_url:
url: "{{ download_urls.joomla }}"
dest: /tmp/joomla-6.0.zip
timeout: 120
force: yes
when: not joomla_exists.stat.exists
- name: Extraer Joomla
unarchive:
src: /tmp/joomla-6.0.zip
dest: /var/www/html/joomla/
remote_src: yes
owner: www-data
group: www-data
when: not joomla_exists.stat.exists
- name: Establecer permisos Joomla
file:
path: /var/www/html/joomla
owner: www-data
group: www-data
recurse: yes
mode: '0755'
- name: Configurar VirtualHost Joomla
template:
src: joomla.conf.j2
dest: /etc/apache2/sites-available/joomla.conf
notify: restart apache2
- name: Habilitar sitio Joomla
command: a2ensite joomla
args:
creates: /etc/apache2/sites-enabled/joomla.conf
notify: restart apache2
- name: Informar si Joomla ya existe
debug:
msg: "Joomla ya está instalado, saltando descarga"
when: joomla_exists.stat.exists

View File

@ -0,0 +1,13 @@
<VirtualHost *:{{ ports.joomla }}>
DocumentRoot /var/www/html/joomla
<Directory /var/www/html/joomla/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>

View File

@ -0,0 +1,5 @@
---
- name: restart apache2
service:
name: apache2
state: restarted

View File

@ -0,0 +1,74 @@
---
- name: Verificar si Nextcloud ya existe
stat:
path: /var/www/html/nextcloud
register: nextcloud_exists
- name: Crear base de datos PostgreSQL para Nextcloud
postgresql_db:
name: nextcloud
state: present
become_user: postgres
when: not nextcloud_exists.stat.exists
- name: Crear usuario PostgreSQL para Nextcloud
postgresql_user:
name: nextcloud
password: "{{ core_password }}"
state: present
become_user: postgres
when: not nextcloud_exists.stat.exists
- name: Otorgar privilegios al usuario Nextcloud
postgresql_privs:
database: nextcloud
roles: nextcloud
privs: ALL
type: database
become_user: postgres
when: not nextcloud_exists.stat.exists
- name: Descargar Nextcloud 31
get_url:
url: "{{ download_urls.nextcloud }}"
dest: /tmp/nextcloud-31.tar.bz2
when: not nextcloud_exists.stat.exists
- name: Extraer Nextcloud
unarchive:
src: /tmp/nextcloud-31.tar.bz2
dest: /var/www/html/
remote_src: yes
when: not nextcloud_exists.stat.exists
- name: Establecer permisos Nextcloud
file:
path: /var/www/html/nextcloud
owner: www-data
group: www-data
recurse: yes
- name: Crear directorio de datos Nextcloud
file:
path: "{{ data_root }}/nextcloud"
state: directory
owner: www-data
group: www-data
mode: '0750'
- name: Configurar VirtualHost Nextcloud
template:
src: nextcloud.conf.j2
dest: /etc/apache2/sites-available/nextcloud.conf
notify: restart apache2
- name: Habilitar sitio Nextcloud
command: a2ensite nextcloud
args:
creates: /etc/apache2/sites-enabled/nextcloud.conf
notify: restart apache2
- name: Informar si Nextcloud ya existe
debug:
msg: "Nextcloud ya está instalado, saltando descarga"
when: nextcloud_exists.stat.exists

View File

@ -0,0 +1,17 @@
<VirtualHost *:{{ ports.nextcloud }}>
DocumentRoot /var/www/html/nextcloud
<Directory /var/www/html/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>

View File

@ -0,0 +1,203 @@
---
# Crear todos los directorios de datos
- name: Crear directorios para apps Docker
file:
path: "{{ data_root }}/{{ item }}"
state: directory
mode: '0755'
loop:
- teable
- teable/db
- wikijs
- wikijs/db
- activepieces
- activepieces/db
- leantime
- leantime/db
- vaultwarden
- pretix
- pretix/db
- pretix/redis
- ontime
- opensign
- opensign/db
- metabase
- gotenberg
# TEABLE
- name: Desplegar Teable Stack
community.docker.docker_compose_v2:
project_name: teable
definition:
version: '3.8'
services:
teable-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: teable
POSTGRES_USER: teable
POSTGRES_PASSWORD: "{{ core_password }}"
volumes:
- "{{ data_root }}/teable/db:/var/lib/postgresql/data"
networks:
- alicante-net
teable:
image: ghcr.io/teableio/teable:latest
restart: unless-stopped
ports:
- "{{ ports.teable }}:3000"
environment:
DATABASE_URL: "postgresql://teable:{{ core_password }}@teable-db:5432/teable"
REDIS_HOST: teable-redis
REDIS_PORT: 6379
PUBLIC_ORIGIN: "http://{{ core_ip }}:{{ ports.teable }}"
volumes:
- "{{ data_root }}/teable:/app/.assets"
networks:
- alicante-net
depends_on:
- teable-db
- teable-redis
teable-redis:
image: redis:7-alpine
restart: unless-stopped
networks:
- alicante-net
networks:
alicante-net:
external: true
# WIKI.JS
- name: Desplegar Wiki.js Stack
community.docker.docker_compose_v2:
project_name: wikijs
definition:
version: '3.8'
services:
wikijs-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: wikijs
POSTGRES_USER: wikijs
POSTGRES_PASSWORD: "{{ core_password }}"
volumes:
- "{{ data_root }}/wikijs/db:/var/lib/postgresql/data"
networks:
- alicante-net
wikijs:
image: ghcr.io/requarks/wiki:2
restart: unless-stopped
ports:
- "{{ ports.wikijs }}:3000"
environment:
DB_TYPE: postgres
DB_HOST: wikijs-db
DB_PORT: 5432
DB_USER: wikijs
DB_PASS: "{{ core_password }}"
DB_NAME: wikijs
networks:
- alicante-net
depends_on:
- wikijs-db
networks:
alicante-net:
external: true
# GOTENBERG
- name: Desplegar Gotenberg
community.docker.docker_container:
name: gotenberg
image: gotenberg/gotenberg:8
restart_policy: unless-stopped
ports:
- "{{ ports.gotenberg }}:3000"
networks:
- name: alicante-net
# METABASE
- name: Desplegar Metabase
community.docker.docker_container:
name: metabase
image: metabase/metabase:latest
restart_policy: unless-stopped
ports:
- "{{ ports.metabase }}:3000"
volumes:
- "{{ data_root }}/metabase:/metabase-data"
env:
MB_DB_FILE: /metabase-data/metabase.db
networks:
- name: alicante-net
# LEANTIME
- name: Desplegar Leantime Stack
community.docker.docker_compose_v2:
project_name: leantime
definition:
version: '3.8'
services:
leantime-db:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "{{ core_password }}"
MYSQL_DATABASE: leantime
MYSQL_USER: leantime
MYSQL_PASSWORD: "{{ core_password }}"
volumes:
- "{{ data_root }}/leantime/db:/var/lib/mysql"
networks:
- alicante-net
leantime:
image: leantime/leantime:latest
restart: unless-stopped
ports:
- "{{ ports.leantime }}:80"
environment:
LEAN_DB_HOST: leantime-db
LEAN_DB_USER: leantime
LEAN_DB_PASSWORD: "{{ core_password }}"
LEAN_DB_DATABASE: leantime
networks:
- alicante-net
depends_on:
- leantime-db
networks:
alicante-net:
external: true
# VAULTWARDEN
- name: Desplegar Vaultwarden
community.docker.docker_container:
name: vaultwarden
image: vaultwarden/server:latest
restart_policy: unless-stopped
ports:
- "{{ ports.vaultwarden }}:80"
volumes:
- "{{ data_root }}/vaultwarden:/data"
networks:
- name: alicante-net
# ONTIME
- name: Desplegar Ontime
community.docker.docker_container:
name: ontime
image: getontime/ontime:latest
restart_policy: unless-stopped
ports:
- "{{ ports.ontime }}:4001"
volumes:
- "{{ data_root }}/ontime:/data"
networks:
- name: alicante-net

View File

@ -0,0 +1,31 @@
---
- name: Actualizar sistema base
apt:
update_cache: yes
upgrade: dist
- name: Instalar paquetes básicos
apt:
name:
- curl
- wget
- git
- htop
- vim
- unzip
- acl
- gnupg2
- ca-certificates
- apt-transport-https
state: present
- name: Crear directorios de datos
file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ data_root }}"
- "{{ docker_root }}"
- "{{ data_root }}/backups"
- /var/www/html

View File

@ -0,0 +1,60 @@
---
- name: Instalar dependencias Python para Docker
apt:
name:
- python3-requests
- python3-docker
state: present
- name: Verificar si Docker está instalado
stat:
path: /usr/bin/docker
register: docker_exists
- name: Instalar Docker
shell: curl -fsSL https://get.docker.com | sh
when: not docker_exists.stat.exists
- name: Instalar Docker Compose v2
shell: |
mkdir -p /usr/local/lib/docker/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
args:
creates: /usr/local/lib/docker/cli-plugins/docker-compose
- name: Crear red Docker compartida
community.docker.docker_network:
name: alicante-net
driver: bridge
- name: Crear directorio para Dockge
file:
path: "{{ docker_root }}/dockge"
state: directory
- name: Verificar si Dockge ya existe
community.docker.docker_container_info:
name: dockge
register: dockge_info
ignore_errors: yes
- name: Desplegar Dockge (solo si no existe)
community.docker.docker_container:
name: dockge
image: louislam/dockge:1
restart_policy: unless-stopped
ports:
- "{{ ports.dockge }}:5001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- "{{ data_root }}/dockge:/app/data"
- "{{ docker_root }}:/opt/stacks"
env:
TZ: "{{ timezone }}"
when: not dockge_info.exists
- name: Informar si Dockge ya existe
debug:
msg: "Dockge ya está corriendo en el puerto {{ ports.dockge }}"
when: dockge_info.exists

View File

@ -0,0 +1,5 @@
---
- name: restart apache2
service:
name: apache2
state: restarted

View File

@ -0,0 +1,95 @@
---
- name: Añadir repositorio SURY para PHP multiversión
shell: |
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
apt-get update
args:
creates: /etc/apt/sources.list.d/php.list
- name: Instalar Apache2
apt:
name:
- apache2
- libapache2-mod-fcgid
state: present
- name: Instalar PHP 8.1, 8.2 y 8.3
apt:
name:
- php8.1
- php8.1-fpm
- php8.1-mysql
- php8.1-pgsql
- php8.1-gd
- php8.1-mbstring
- php8.1-xml
- php8.1-zip
- php8.1-intl
- php8.1-curl
- php8.2
- php8.2-fpm
- php8.2-mysql
- php8.2-pgsql
- php8.2-gd
- php8.2-mbstring
- php8.2-xml
- php8.2-zip
- php8.2-intl
- php8.2-curl
- php8.3
- php8.3-fpm
- php8.3-mysql
- php8.3-pgsql
- php8.3-gd
- php8.3-mbstring
- php8.3-xml
- php8.3-zip
- php8.3-intl
- php8.3-curl
- php8.3-apcu
- php8.3-redis
state: present
- name: Instalar dependencias Python para Ansible
apt:
name:
- python3-psycopg2
- python3-pymysql
state: present
- name: Habilitar módulos Apache necesarios
apache2_module:
name: "{{ item }}"
state: present
loop:
- rewrite
- proxy
- proxy_fcgi
- setenvif
notify: restart apache2
- name: Instalar Redis Server
apt:
name: redis-server
state: present
- name: Configurar puertos adicionales en Apache
lineinfile:
path: /etc/apache2/ports.conf
line: "Listen {{ item }}"
create: yes
loop:
- "{{ ports.nextcloud }}"
- "{{ ports.joomla }}"
- "{{ ports.dolibarr }}"
notify: restart apache2
- name: Iniciar y habilitar servicios
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- apache2
- redis-server