initial commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "roles/docker_compose_app"]
|
||||||
|
path = roles/docker_compose_app
|
||||||
|
url = ssh://git@ssh.git.jaroszew.ski:2222/ansible/ansible-role-docker-compose-app.git
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
# Ansible Collection - patrickj.docker_apps
|
||||||
|
|
||||||
|
A comprehensive Ansible collection for deploying and managing Docker Compose applications with enterprise-grade features including backup/restore, health checks, and automated updates.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A curated collection of Docker Compose roles for self-hosted applications. Each role leverages the `docker_compose_app` base to provide standardized deployment, configuration management, backup procedures, and lifecycle operations across diverse containerized services.
|
||||||
|
|
||||||
|
Consult the [role development documentation](https://git.jaroszew.ski/ansible/ansible-role-docker-compose-app/src/branch/main/README.md) for guidance on creating custom roles, variable conventions, and integration patterns.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **🏗️ Template-based deployment** with Jinja2 templating
|
||||||
|
- **🔄 Backup & restore system** (store backups on the Ansible controller + remote host)
|
||||||
|
- **🏥 Health checks** and deployment verification
|
||||||
|
- **🏷️ Tag-based execution** for selective operations
|
||||||
|
- **📦 Multiple deployment modes** (template, file, or inline content)
|
||||||
|
- **🔧 Flexible directory management**
|
||||||
|
- **⚙️ Configurable retention policies**
|
||||||
|
- **🔄 Container update automation**
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### From Git Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-galaxy collection install https://git.jaroszew.ski/ansible/ansible-collection-docker-apps.git
|
||||||
|
```
|
||||||
|
|
||||||
|
### From Local Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the collection directory
|
||||||
|
ansible-galaxy collection install .
|
||||||
|
|
||||||
|
# Or specify path
|
||||||
|
ansible-galaxy collection install /path/to/patrickj/docker_apps
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Basic Deployment
|
||||||
|
|
||||||
|
Create a playbook using the collection roles:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy media server applications
|
||||||
|
hosts: localhost
|
||||||
|
become: yes
|
||||||
|
vars:
|
||||||
|
host_root_path: /opt/docker
|
||||||
|
app_timezone: "America/New_York"
|
||||||
|
roles:
|
||||||
|
- patrickj.docker_apps.open-webui
|
||||||
|
- patrickj.docker_apps.audiobookshelf
|
||||||
|
- patrickj.docker_apps.paperless-ngx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Run the Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full deployment
|
||||||
|
ansible-playbook deploy.yml
|
||||||
|
|
||||||
|
# Setup only (directories, templates - no containers)
|
||||||
|
ansible-playbook --tags setup deploy.yml
|
||||||
|
|
||||||
|
# Deploy specific apps
|
||||||
|
ansible-playbook deploy.yml --limit jellyfin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Roles
|
||||||
|
|
||||||
|
### Media Applications
|
||||||
|
- **`jellyfin`** - Media server for movies, TV shows, music
|
||||||
|
- **`audiobookshelf`** - Audiobook and podcast server
|
||||||
|
- **`navidrome`** - Music streaming server
|
||||||
|
|
||||||
|
### Utilities & Monitoring
|
||||||
|
- **`uptime-kuma`** - Uptime monitoring
|
||||||
|
- **`speedtest-tracker`** - Internet speed monitoring
|
||||||
|
- **`glance`** - Dashboard
|
||||||
|
- **`grafana`** - Data visualization
|
||||||
|
- **`influxdb`** - Time series database
|
||||||
|
|
||||||
|
### Productivity
|
||||||
|
- **`paperless-ngx`** - Document management
|
||||||
|
- **`mealie`** - Recipe manager
|
||||||
|
- **`linkwarden`** - Bookmark manager
|
||||||
|
- **`immich`** - Photo management
|
||||||
|
- **`gitea`** - Git repository server
|
||||||
|
|
||||||
|
### Web Services
|
||||||
|
- **`open-webui`** - Web interface for LLMs
|
||||||
|
- **`redlib`** - Alternative Reddit frontend
|
||||||
|
- **`calibre-web`** - eBook server
|
||||||
|
|
||||||
|
I'll be adding more roles as I incorporate them into my homelab.
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Tag-Based Operations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Setup applications (do not start containers)
|
||||||
|
ansible-playbook --tags setup playbook.yml
|
||||||
|
|
||||||
|
# Full deployment (setup + start containers)
|
||||||
|
ansible-playbook --tags deploy playbook.yml
|
||||||
|
|
||||||
|
# Backup applications
|
||||||
|
ansible-playbook --tags backup playbook.yml
|
||||||
|
|
||||||
|
# Restore from backup then deploy
|
||||||
|
ansible-playbook --tags restore,deploy playbook.yml
|
||||||
|
|
||||||
|
# Update container images
|
||||||
|
ansible-playbook --tags update playbook.yml
|
||||||
|
|
||||||
|
# Backup and update
|
||||||
|
ansible-playbook --tags backup,update playbook.yml
|
||||||
|
|
||||||
|
# Health check only
|
||||||
|
ansible-playbook --tags healthcheck playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Global Variables
|
||||||
|
|
||||||
|
Set these variables in your playbook or inventory:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Required
|
||||||
|
host_root_path: /opt/docker # Base directory for all apps
|
||||||
|
|
||||||
|
# Optional
|
||||||
|
app_timezone: "UTC" # Container timezone
|
||||||
|
app_restart_policy: unless-stopped # Docker restart policy
|
||||||
|
backup_path: /opt/backups # Backup storage location
|
||||||
|
```
|
||||||
|
|
||||||
|
### Per-Application Variables
|
||||||
|
|
||||||
|
Each application role accepts specific configuration. See individual role documentation in `roles/<app_name>/README.md`.
|
||||||
|
|
||||||
|
Common patterns:
|
||||||
|
```yaml
|
||||||
|
app_name: custom-instance-name # Override default name
|
||||||
|
{app}_http_port: 8080 # Custom port
|
||||||
|
{app}_config_path: /custom/path # Override paths
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup & Restore
|
||||||
|
|
||||||
|
### Automated Backups
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create backups for all deployed applications
|
||||||
|
ansible-playbook --tags backup site.yml
|
||||||
|
|
||||||
|
# Schedule daily backups (cron)
|
||||||
|
0 2 * * * ansible-playbook --tags backup /path/to/playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore Operations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restore latest backup
|
||||||
|
ansible-playbook --tags restore playbook.yml
|
||||||
|
|
||||||
|
# Full restore workflow (setup + restore + deploy)
|
||||||
|
ansible-playbook --tags setup,restore,deploy playbook.yml
|
||||||
|
|
||||||
|
# Restore specific archive
|
||||||
|
ansible-playbook --tags restore playbook.yml \
|
||||||
|
-e app_restore_archive=/path/to/backup.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- **Ansible**: >= 2.14
|
||||||
|
- **Docker**: >= 20.10
|
||||||
|
- **Docker Compose**: >= 2.0
|
||||||
|
- **Python**: >= 3.8
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
The collection automatically handles dependencies:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
collections:
|
||||||
|
- community.docker # For Docker Compose operations
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Adding New Applications
|
||||||
|
|
||||||
|
1. Create role directory: `roles/new-app/`
|
||||||
|
2. Follow the template structure from existing roles
|
||||||
|
3. Configure meta dependency on `docker_compose_app`
|
||||||
|
4. Add to documentation
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test role syntax
|
||||||
|
ansible-playbook --syntax-check playbook.yml
|
||||||
|
|
||||||
|
# Test specific role
|
||||||
|
ansible-playbook --tags setup --check playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
Patrick Jaroszewski
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
namespace: patrickj
|
||||||
|
name: docker_apps
|
||||||
|
version: 1.0.0
|
||||||
|
readme: README.md
|
||||||
|
authors:
|
||||||
|
- Patrick Jaroszewski
|
||||||
|
description: Ansible collection for deploying Docker Compose applications
|
||||||
|
license:
|
||||||
|
- MIT
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
- compose
|
||||||
|
- containers
|
||||||
|
- selfhosted
|
||||||
|
- homelab
|
||||||
|
dependencies:
|
||||||
|
"community.docker": ">=1.10.0"
|
||||||
|
repository: https://git.jaroszew.ski/ansible/ansible-collection-docker-apps
|
||||||
|
documentation: https://git.jaroszew.ski/ansible/ansible-collection-docker-apps/README.md
|
||||||
|
homepage: https://git.jaroszew.ski/ansible/ansible-collection-docker-apps
|
||||||
|
issues: https://git.jaroszew.ski/ansible/ansible-collection-docker-apps/issues
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Audiobookshelf
|
||||||
|
|
||||||
|
Deploy Audiobookshelf audiobook and podcast server using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Audiobookshelf is a self-hosted audiobook and podcast server with mobile apps, chapter support, and progress tracking.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `audiobookshelf_libraries` | List of media library mappings with `host_path` and `container_path` |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `audiobookshelf_http_port` | `13378` | Web interface port |
|
||||||
|
| `audiobookshelf_config_path` | `{{ app_dir }}/config` | Configuration storage |
|
||||||
|
| `audiobookshelf_metadata_path` | `{{ app_dir }}/metadata` | Metadata cache storage |
|
||||||
|
| `audiobookshelf_container_version` | `latest` | Audiobookshelf Docker image tag |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.audiobookshelf
|
||||||
|
vars:
|
||||||
|
audiobookshelf_libraries:
|
||||||
|
- host_path: /storage/audiobooks
|
||||||
|
container_path: /audiobooks
|
||||||
|
```
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
app_role_name: audiobookshelf
|
||||||
|
app_name: audiobookshelf
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
audiobookshelf_container_name: "{{ app_name | default('audiobookshelf') }}"
|
||||||
|
audiobookshelf_container_version: latest
|
||||||
|
audiobookshelf_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
audiobookshelf_http_port: 13378
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
audiobookshelf_config_path: "{{ app_dir }}/config"
|
||||||
|
audiobookshelf_metadata_path: "{{ app_dir }}/metadata"
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Audiobookshelf with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: audiobookshelf
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ audiobookshelf_config_path }}"
|
||||||
|
- "{{ audiobookshelf_metadata_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ audiobookshelf_config_path }}"
|
||||||
|
- "{{ audiobookshelf_metadata_path }}"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
audiobookshelf:
|
||||||
|
image: "ghcr.io/advplyr/audiobookshelf:{{ audiobookshelf_container_version }}"
|
||||||
|
container_name: "{{ audiobookshelf_container_name }}"
|
||||||
|
restart: "{{ audiobookshelf_restart_policy }}"
|
||||||
|
ports:
|
||||||
|
- "{{ audiobookshelf_http_port }}:80"
|
||||||
|
volumes:
|
||||||
|
- "{{ audiobookshelf_config_path }}:/config"
|
||||||
|
- "{{ audiobookshelf_metadata_path }}:/metadata"
|
||||||
|
{% for item in audiobookshelf_libraries %}
|
||||||
|
- "{{ item.host_path }}:{{ item.container_path }}"
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Calibre-Web
|
||||||
|
|
||||||
|
Deploy Calibre-Web ebook server using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks from a Calibre database.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `calibre_web_library_path` | Path to existing Calibre library directory |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `calibre_web_http_port` | `8083` | Web interface port |
|
||||||
|
| `calibre_web_config_path` | `{{ app_dir }}/config` | Configuration storage |
|
||||||
|
| `calibre_web_container_version` | `latest` | Calibre-Web Docker image tag |
|
||||||
|
| `calibre_web_uid` | `{{ app_uid }}` | User ID for file permissions |
|
||||||
|
| `calibre_web_gid` | `{{ app_gid }}` | Group ID for file permissions |
|
||||||
|
| `calibre_web_timezone` | `{{ app_timezone }}` | Container timezone |
|
||||||
|
| `calibre_web_docker_mods` | `linuxserver/mods:universal-calibre` | Adds ebook conversion capability (x86-64 only) |
|
||||||
|
| `calibre_web_oauth_relax` | `1` | Allows Google OAuth to work. Set to `0` to disable |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.calibre-web
|
||||||
|
vars:
|
||||||
|
calibre_web_library_path: /storage/ebooks/calibre-library
|
||||||
|
```
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
app_name: calibre-web
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
calibre_web_container_name: "{{ app_name | default('calibre-web') }}"
|
||||||
|
calibre_web_container_version: latest
|
||||||
|
calibre_web_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
calibre_web_uid: "{{ app_uid }}"
|
||||||
|
calibre_web_gid: "{{ app_gid }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
calibre_web_http_port: 8083
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
calibre_web_config_path: "{{ app_dir }}/config"
|
||||||
|
calibre_web_library_path: "{{ app_dir }}/library"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
calibre_web_timezone: "{{ app_timezone | default('Etc/UTC') }}"
|
||||||
|
calibre_web_docker_mods: "linuxserver/mods:universal-calibre"
|
||||||
|
calibre_web_oauth_relax: "1"
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Calibre-Web with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: calibre-web
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ calibre_web_config_path }}"
|
||||||
|
- "{{ calibre_web_books_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ calibre_web_config_path }}"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
calibre-web:
|
||||||
|
image: "lscr.io/linuxserver/calibre-web:{{ calibre_web_container_version }}"
|
||||||
|
container_name: "{{ calibre_web_container_name }}"
|
||||||
|
restart: "{{ calibre_web_restart_policy }}"
|
||||||
|
ports:
|
||||||
|
- "{{ calibre_web_http_port }}:8083"
|
||||||
|
environment:
|
||||||
|
- PUID={{ calibre_web_uid }}
|
||||||
|
- PGID={{ calibre_web_gid }}
|
||||||
|
- TZ={{ calibre_web_timezone }}
|
||||||
|
- DOCKER_MODS={{ calibre_web_docker_mods }}
|
||||||
|
- OAUTHLIB_RELAX_TOKEN_SCOPE={{ calibre_web_oauth_relax }}
|
||||||
|
volumes:
|
||||||
|
- "{{ calibre_web_config_path }}:/config"
|
||||||
|
- "{{ calibre_web_library_path }}:/books"
|
||||||
Submodule
+1
Submodule roles/docker_compose_app added at 4211fad10c
@@ -0,0 +1,3 @@
|
|||||||
|
# ---> Ansible
|
||||||
|
*.retry
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 ansible
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
|
following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
|
portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -0,0 +1,512 @@
|
|||||||
|
# Ansible Role: gitea
|
||||||
|
|
||||||
|
This Ansible role automates the deployment of Gitea - a self-hosted Git service, using Docker Compose. It provides a comprehensive setup with support for runners, fail2ban integration, and extensive configuration options. This role uses the centralized `docker_compose_app` role for standardized deployment, backup/restore, and health checks.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- **Standardized deployment** - Uses `docker_compose_app` for consistent deployment patterns
|
||||||
|
- **Docker-based deployment** - Runs Gitea in a rootless container for enhanced security
|
||||||
|
- **Complete security configuration** - Password policies, 2FA, fail2ban integration, etc.
|
||||||
|
- **Enterprise backup/restore** - Dual storage system with configurable retention policies
|
||||||
|
- **Health monitoring** - Automated health checks and deployment verification
|
||||||
|
- **Gitea Actions support** - Supports creating multiple runners running in rootless containers using DinD (Docker-in-Docker)
|
||||||
|
- **User management** - Automated user creation and removal
|
||||||
|
- **Extensible** - Extra config variables for any Gitea setting not explicitly defined
|
||||||
|
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Docker and Docker Compose installed (handled by `geerlingguy.docker` dependency)
|
||||||
|
- jmespath Python library (install with: `pip install jmespath`)
|
||||||
|
|
||||||
|
## Sample Usage in a Playbook
|
||||||
|
The following playbook was tested on the latest Debian 12, it should work on Ubuntu as well.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Installs Docker and Compose if not available
|
||||||
|
- name: Install Gitea using Docker Compose
|
||||||
|
hosts: git.example.com
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- role: gitea
|
||||||
|
vars:
|
||||||
|
# The default vars assume you are running a reverse proxy that handles HTTPS
|
||||||
|
app_name: gitea-prod
|
||||||
|
gitea_fqdn: 'git.example.com'
|
||||||
|
gitea_root_url: 'https://git.example.com'
|
||||||
|
gitea_protocol: http
|
||||||
|
gitea_http_listen: '0.0.0.0'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup and Restore
|
||||||
|
|
||||||
|
This role uses the standardized backup/restore system from `docker_compose_app`, providing dual storage (controller + remote host) with configurable retention policies.
|
||||||
|
|
||||||
|
### Creating a Backup
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Create Gitea backup
|
||||||
|
hosts: git.example.com
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- role: gitea
|
||||||
|
vars:
|
||||||
|
app_name: gitea-prod
|
||||||
|
app_backup: true
|
||||||
|
app_backup_retention_days_controller: 90
|
||||||
|
app_backup_retention_days_remote: 7
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restoring from Backup
|
||||||
|
|
||||||
|
Restore from latest backup:
|
||||||
|
```yaml
|
||||||
|
- name: Restore Gitea from latest backup
|
||||||
|
hosts: git.example.com
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- role: gitea
|
||||||
|
vars:
|
||||||
|
app_name: gitea-prod
|
||||||
|
app_restore: true
|
||||||
|
app_restore_source: controller # or 'remote'
|
||||||
|
```
|
||||||
|
|
||||||
|
Restore from specific archive:
|
||||||
|
```yaml
|
||||||
|
- name: Restore Gitea from specific backup
|
||||||
|
hosts: git.example.com
|
||||||
|
become: yes
|
||||||
|
roles:
|
||||||
|
- role: gitea
|
||||||
|
vars:
|
||||||
|
app_name: gitea-prod
|
||||||
|
app_restore: true
|
||||||
|
app_restore_source: controller
|
||||||
|
app_restore_archive: /path/to/gitea-20240315-120000.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Restore operations will **completely replace** all existing Gitea data.
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
|
||||||
|
## Standardized Variables
|
||||||
|
|
||||||
|
This role uses the standardized `docker_compose_app` pattern. Core variables include:
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `app_name` | Required | Unique application instance name |
|
||||||
|
| `app_dir` | `{{ host_root_path }}/{{ app_name }}` | Application directory |
|
||||||
|
| `app_uid` | `{{ ansible_facts.user_uid }}` | File ownership UID |
|
||||||
|
| `app_gid` | `{{ ansible_facts.user_gid }}` | File ownership GID |
|
||||||
|
| `app_permission_mode` | `"0640"` | File permission mode |
|
||||||
|
| `app_restart_policy` | `"unless-stopped"` | Docker restart policy |
|
||||||
|
| `app_subdirectories` | `['data', 'config', 'log']` | Directories created in app_dir |
|
||||||
|
|
||||||
|
## Container Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_container_name` | `{{ app_name \| default('gitea') }}` | Docker container name for the Gitea service |
|
||||||
|
| `gitea_container_version` | `latest-rootless` | Docker image tag for the Gitea container (e.g., `latest-rootless`, `1.21.5-rootless`) |
|
||||||
|
| `gitea_restart_policy` | `{{ app_restart_policy }}` | Container restart policy (unless-stopped, always, on-failure, no) |
|
||||||
|
| `gitea_http_port` | `3000` | Host port that maps to Gitea's web interface |
|
||||||
|
| `gitea_ssh_port` | `2222` | Host port that maps to Gitea's SSH server |
|
||||||
|
| `gitea_data_path` | `{{ app_dir }}/data` | Full path to Gitea data directory on the host |
|
||||||
|
| `gitea_config_path` | `{{ app_dir }}/config` | Full path to Gitea configuration directory on the host |
|
||||||
|
| `gitea_log_path` | `{{ app_dir }}/log` | Full path to Gitea log directory on the host |
|
||||||
|
|
||||||
|
## Initial User Setup
|
||||||
|
|
||||||
|
| Variable Name | Option | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_users` | `[]` | List of user objects to create or remove in Gitea |
|
||||||
|
| | `username` | Login username for the Gitea user |
|
||||||
|
| | `email` | Email address for the Gitea user |
|
||||||
|
| | `password` | Password for the user (should be encrypted with Ansible Vault) |
|
||||||
|
| | `must_change_password` | If `true`, user must change password on first login |
|
||||||
|
| | `admin` | If `true`, user is created with administrator privileges |
|
||||||
|
| | `state` | Set to `present` to create user or `absent` to delete user |
|
||||||
|
|
||||||
|
## Backup and Restore
|
||||||
|
|
||||||
|
Backup and restore functionality is provided by the `docker_compose_app` role. Use the standard backup/restore variables:
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `app_backup` | `false` | Enable backup functionality |
|
||||||
|
| `app_backup_subdirectories` | `['data', 'config']` | Directories to backup (relative to app_dir) |
|
||||||
|
| `app_restore` | `false` | Enable restore functionality |
|
||||||
|
| `app_restore_source` | `controller` | Restore source (`controller` or `remote`) |
|
||||||
|
| `app_restore_archive` | - | Specific archive file to restore (overrides latest) |
|
||||||
|
| `app_backup_retention_days_controller` | `90` | Controller backup retention in days |
|
||||||
|
| `app_backup_retention_days_remote` | `7` | Remote backup retention in days |
|
||||||
|
|
||||||
|
## Runners Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_runner_global_registration_token` | `""` | Global registration token that applies to all runners (can be found in Gitea admin settings) |
|
||||||
|
| `gitea_runner_image` | `gitea/act_runner` | Docker image for Gitea Actions runners |
|
||||||
|
| `gitea_runner_container_version` | `latest-dind-rootless` | Docker image tag for runner containers |
|
||||||
|
| `gitea_runner_restart_policy` | `{{ gitea_restart_policy }}` | Container restart policy for runners |
|
||||||
|
| `gitea_runners` | `{}` | Dictionary of Gitea Actions runner configurations |
|
||||||
|
|
||||||
|
### Runner Configuration Options
|
||||||
|
|
||||||
|
Each runner in the `gitea_runners` dictionary supports these options:
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `name` | Unique name identifier for the runner |
|
||||||
|
| `data_mount` | Path relative to app_dir for persistent runner data storage |
|
||||||
|
| `config_file_mount` | Path relative to app_dir for runner configuration files |
|
||||||
|
| `cache_enabled` | If `true`, enables action cache functionality (for `actions/cache` support) |
|
||||||
|
| `cache_port` | Port number on the host for accessing the runner's cache service (must be unique per runner) |
|
||||||
|
| `registration_token` | Runner-specific registration token (optional if `gitea_runner_global_registration_token` is set) |
|
||||||
|
|
||||||
|
## Fail2Ban Security
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_fail2ban_enabled` | `false` | Enable fail2ban protection to automatically ban IPs after failed login attempts |
|
||||||
|
| `gitea_fail2ban_jail_maxretry` | `10` | Number of failed login attempts before an IP is banned |
|
||||||
|
| `gitea_fail2ban_jail_findtime` | `3600` | Time window in seconds during which failed attempts are counted |
|
||||||
|
| `gitea_fail2ban_jail_bantime` | `900` | Duration in seconds that an IP remains banned |
|
||||||
|
| `gitea_fail2ban_jail_action` | `iptables-allports[chain="FORWARD"]` | Fail2ban action/rule to execute when banning an IP |
|
||||||
|
|
||||||
|
## Overall Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_app_name` | `Gitea` | Application name displayed throughout the Gitea interface |
|
||||||
|
| `gitea_user` | `gitea` | System username that runs the Gitea process inside the container |
|
||||||
|
| `gitea_run_mode` | `prod` | Application run mode: `prod` (production), `dev` (development), or `test` |
|
||||||
|
| `gitea_fqdn` | `localhost` | Fully qualified domain name for accessing the Gitea instance |
|
||||||
|
|
||||||
|
## Server Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_protocol` | `http` | Protocol for the root URL: `http` or `https` |
|
||||||
|
| `gitea_http_domain` | `{{ gitea_fqdn }}` | Domain name used in HTTP headers and clone URLs |
|
||||||
|
| `gitea_root_url` | `{{ gitea_protocol }}://{{ gitea_fqdn }}` | Full public URL where Gitea is accessible |
|
||||||
|
| `gitea_http_listen` | `127.0.0.1` | IP address the HTTP server binds to; use `0.0.0.0` to allow external access |
|
||||||
|
| `gitea_internal_http_port` | `3000` | Port number Gitea listens on inside the container |
|
||||||
|
| `gitea_internal_ssh_port` | `2222` | Port number SSH server listens on inside the container |
|
||||||
|
| `gitea_ssh_listen` | `0.0.0.0` | IP address the SSH server binds to |
|
||||||
|
| `gitea_ssh_domain` | `{{ gitea_http_domain }}` | Domain name shown in SSH clone URLs |
|
||||||
|
| `gitea_start_ssh` | `true` | Enable or disable the built-in SSH server |
|
||||||
|
| `gitea_landing_page` | `home` | Default page for non-authenticated users: `home`, `explore`, `organizations`, or `login` |
|
||||||
|
| `gitea_server_extra_config` | `{}` | Dictionary of additional server configuration options not covered above |
|
||||||
|
|
||||||
|
## Security Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_secret_key` | | Secret key used for encrypting cookies and tokens (generate with `gitea generate secret SECRET_KEY`) |
|
||||||
|
| `gitea_internal_token` | | Token used for internal API authentication (generate with `gitea generate secret INTERNAL_TOKEN`) |
|
||||||
|
| `gitea_install_lock` | `false` | If `true`, prevents the installation wizard from running |
|
||||||
|
| `gitea_disable_git_hooks` | `true` | If `true`, disables custom Git hooks for security |
|
||||||
|
| `gitea_disable_webhooks` | `false` | If `true`, disables all webhook functionality |
|
||||||
|
| `gitea_reverse_proxy_limit` | `1` | Number of reverse proxy hops to trust for obtaining the real client IP |
|
||||||
|
| `gitea_reverse_proxy_trusted_proxies` | `127.0.0.0/8,::1/128` | Comma-separated list of trusted proxy IP addresses or CIDR ranges |
|
||||||
|
| `gitea_password_complexity` | `off` | Password requirements: `off`, or comma-separated list of `lower`, `upper`, `digit`, `spec` |
|
||||||
|
| `gitea_password_min_length` | `8` | Minimum number of characters required for passwords |
|
||||||
|
| `gitea_password_check_pwn` | `false` | If `true`, checks passwords against the HaveIBeenPwned breach database |
|
||||||
|
| `gitea_2fa` | | Two-factor authentication setting; set to `enforced` to require 2FA for all users |
|
||||||
|
| `gitea_login_remember_days` | `31` | Number of days to keep users logged in when they select "Remember Me" |
|
||||||
|
| `gitea_cookie_remember_name` | `gitea_incredible` | Name of the cookie used for "Remember Me" functionality |
|
||||||
|
| `gitea_security_extra_config` | `{}` | Dictionary of additional security configuration options |
|
||||||
|
|
||||||
|
## Service Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_disable_registration` | `false` | If `true`, disables new user registration entirely |
|
||||||
|
| `gitea_register_email_confirm` | `false` | If `true`, requires email verification to complete registration |
|
||||||
|
| `gitea_register_manual_confirm` | `false` | If `true`, requires admin approval for new registrations |
|
||||||
|
| `gitea_require_signin_view` | `false` | If `true`, requires users to sign in to view any content |
|
||||||
|
| `gitea_enable_notify_mail` | `false` | If `true`, enables email notifications for events |
|
||||||
|
| `gitea_enable_captcha` | `false` | If `true`, shows CAPTCHA on registration form |
|
||||||
|
| `gitea_captcha_type` | `image` | Type of CAPTCHA to use: `image`, `recaptcha`, `hcaptcha`, or `mcaptcha` |
|
||||||
|
| `gitea_show_registration_button` | `true` | If `true`, displays registration button on login page |
|
||||||
|
| `gitea_default_keep_email_private` | `false` | If `true`, new users have email privacy enabled by default |
|
||||||
|
| `gitea_default_allow_create_organization` | `true` | If `true`, new users can create organizations |
|
||||||
|
| `gitea_default_user_is_restricted` | `false` | If `true`, new users are created with restricted permissions |
|
||||||
|
| `gitea_default_user_visibility` | `public` | Default visibility for new user profiles: `public`, `limited`, or `private` |
|
||||||
|
| `gitea_default_org_visibility` | `public` | Default visibility for new organizations: `public`, `limited`, or `private` |
|
||||||
|
| `gitea_default_org_member_visible` | `false` | If `true`, organization members are visible by default |
|
||||||
|
| `gitea_allow_only_internal_registration` | `false` | If `true`, only allows registration via internal authentication |
|
||||||
|
| `gitea_allow_only_external_registration` | `false` | If `true`, only allows registration via external authentication sources |
|
||||||
|
| `gitea_email_domain_allowlist` | | Comma-separated list of allowed email domains for registration |
|
||||||
|
| `gitea_email_domain_blocklist` | | Comma-separated list of blocked email domains for registration |
|
||||||
|
| `gitea_no_reply_address` | | No-reply email address used for system-generated emails |
|
||||||
|
| `gitea_enable_user_heatmap` | `true` | If `true`, displays user activity heatmap on profiles |
|
||||||
|
| `gitea_enable_timetracking` | `true` | If `true`, enables time tracking features for issues |
|
||||||
|
| `gitea_auto_watch_new_repos` | `true` | If `true`, users automatically watch repositories they create |
|
||||||
|
| `gitea_auto_watch_on_changes` | `false` | If `true`, users automatically watch repositories they contribute to |
|
||||||
|
| `gitea_show_milestones_dashboard_page` | `true` | If `true`, shows milestones on the dashboard page |
|
||||||
|
| `gitea_service_extra_config` | `{}` | Dictionary of additional service configuration options |
|
||||||
|
|
||||||
|
## Repository Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_repo_force_private` | `false` | If `true`, forces all new repositories to be private |
|
||||||
|
| `gitea_repo_default_private` | `last` | Default visibility for new repositories: `public`, `private`, or `last` (uses last selection) |
|
||||||
|
| `gitea_repo_default_push_create_private` | `true` | If `true`, repositories created via push are private by default |
|
||||||
|
| `gitea_repo_preferred_licenses` | `Apache License 2.0,MIT License` | Comma-separated list of license names to show at the top when creating repositories |
|
||||||
|
| `gitea_repo_disable_http_git` | `false` | If `true`, disables HTTP(S) Git operations (clone, push, pull) |
|
||||||
|
| `gitea_repo_disable_migrations` | `false` | If `true`, disables repository migration feature |
|
||||||
|
| `gitea_repo_disable_stars` | `false` | If `true`, disables the ability to star repositories |
|
||||||
|
| `gitea_repo_default_branch` | `main` | Default branch name for new repositories |
|
||||||
|
| `gitea_repository_extra_config` | `{}` | Dictionary of additional repository configuration options |
|
||||||
|
|
||||||
|
## CORS Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_cors_enabled` | `false` | Enable Cross-Origin Resource Sharing (CORS) headers |
|
||||||
|
| `gitea_cors_allowed_domains` | `*` | Domains allowed to make cross-origin requests; `*` allows all |
|
||||||
|
| `gitea_cors_allowed_methods` | `GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS` | HTTP methods allowed for cross-origin requests |
|
||||||
|
| `gitea_cors_max_age` | `10m` | Duration to cache preflight CORS request results |
|
||||||
|
| `gitea_cors_allowed_credentials` | `false` | If `true`, allows credentials (cookies, auth headers) in cross-origin requests |
|
||||||
|
| `gitea_cors_headers` | `Content-Type,User-Agent` | Custom headers allowed in cross-origin requests |
|
||||||
|
| `gitea_cors_x_frame_options` | `SAMEORIGIN` | X-Frame-Options header value: `SAMEORIGIN`, `DENY`, or `ALLOW-FROM uri` |
|
||||||
|
|
||||||
|
## UI Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_ui_default_theme` | `gitea-auto` | Default theme for the UI; `gitea-auto` switches based on system preference |
|
||||||
|
| `gitea_ui_themes` | | Comma-separated list of themes to make available; if empty, all themes are available |
|
||||||
|
| `gitea_ui_show_user_email` | `true` | If `true`, displays user email addresses in the UI (respects privacy settings) |
|
||||||
|
| `gitea_ui_show_full_name` | `false` | If `true`, displays full names instead of usernames where applicable |
|
||||||
|
| `gitea_ui_extra_config` | `{}` | Dictionary of additional UI configuration options |
|
||||||
|
|
||||||
|
## UI Meta Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_ui_meta_author` | `Gitea - Git with a cup of tea` | Content for the HTML meta author tag |
|
||||||
|
| `gitea_ui_meta_description` | `Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go` | Content for the HTML meta description tag (used by search engines) |
|
||||||
|
| `gitea_ui_meta_keywords` | `go,git,self-hosted,gitea` | Comma-separated keywords for the HTML meta keywords tag |
|
||||||
|
|
||||||
|
## Indexer Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_issue_indexer_type` | `bleve` | Issue search indexer engine: `bleve` (built-in), `db` (database), `elasticsearch`, or `meilisearch` |
|
||||||
|
| `gitea_issue_indexer_connection_string` | | Connection string for external indexer (required for `elasticsearch` or `meilisearch`) |
|
||||||
|
| `gitea_issue_indexer_name` | `gitea_issues` | Index name used in external indexer services |
|
||||||
|
| `gitea_issue_indexer_path` | `indexers/issues.bleve` | File path for bleve index storage (relative to Gitea data directory) |
|
||||||
|
| `gitea_repo_indexer_enabled` | `false` | Enable code search functionality (WARNING: requires significant disk space, ~6x repository size) |
|
||||||
|
| `gitea_repo_indexer_repo_types` | `sources,forks,mirrors,templates` | Types of repositories to include in code search index |
|
||||||
|
| `gitea_repo_indexer_type` | `bleve` | Code search indexer engine: `bleve` (built-in) or `elasticsearch` |
|
||||||
|
| `gitea_repo_indexer_path` | `indexers/repos.bleve` | File path for bleve code index storage (relative to Gitea data directory) |
|
||||||
|
| `gitea_repo_indexer_connection_string` | | Connection string for elasticsearch code indexer |
|
||||||
|
| `gitea_repo_indexer_name` | `gitea_codes` | Index name for code search in elasticsearch |
|
||||||
|
| `gitea_repo_indexer_include` | | Glob patterns for files to include in code search (e.g., `**.txt,**.md`); empty includes all |
|
||||||
|
| `gitea_repo_indexer_exclude` | | Glob patterns for files to exclude from code search (takes precedence over includes) |
|
||||||
|
| `gitea_repo_indexer_exclude_vendored` | `true` | If `true`, excludes vendored/third-party code from indexing |
|
||||||
|
| `gitea_repo_indexer_max_file_size` | `1048576` | Maximum file size in bytes to index (default 1 MiB); larger files are skipped |
|
||||||
|
| `gitea_indexer_startup_timeout` | `30s` | Maximum time to wait for indexer initialization; `-1` disables timeout |
|
||||||
|
| `gitea_indexer_extra_config` | `{}` | Dictionary of additional indexer configuration options |
|
||||||
|
|
||||||
|
## Packages Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_packages_enabled` | `true` | Enable package registry functionality (for npm, Maven, Docker, etc.) |
|
||||||
|
| `gitea_packages_extra_config` | `{}` | Dictionary of additional package registry configuration options |
|
||||||
|
|
||||||
|
## Actions Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_actions_enabled` | `false` | Enable Gitea Actions (CI/CD pipeline functionality) |
|
||||||
|
| `gitea_actions_default_actions_url` | `github` | Default URL for Actions marketplace; `github`, `self`, or custom URL |
|
||||||
|
| `gitea_actions_extra_config` | `{}` | Dictionary of additional Actions configuration options |
|
||||||
|
|
||||||
|
## Logging Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_log_root_path` | | Root directory for log files; required if `gitea_log_mode` is `file` or for fail2ban integration |
|
||||||
|
| `gitea_log_mode` | `console` | Log output destination: `console`, `file`, `conn` (network), or `smtp` (email) |
|
||||||
|
| `gitea_log_level` | `Info` | Logging verbosity level: `Trace`, `Debug`, `Info`, `Warn`, `Error`, or `Critical` |
|
||||||
|
| `gitea_enable_ssh_log` | `false` | If `true`, enables detailed logging for SSH operations |
|
||||||
|
| `gitea_log_extra_config` | `{}` | Dictionary of additional logging configuration options |
|
||||||
|
|
||||||
|
## Mailer Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_mailer_enabled` | `false` | Enable email functionality for notifications and registration |
|
||||||
|
| `gitea_mailer_protocol` | | Mail protocol: `smtp`, `smtps`, `smtp+starttls`, `smtp+unix`, `sendmail`, or `dummy` (logs only) |
|
||||||
|
| `gitea_mailer_smtp_addr` | | Hostname or IP address of the SMTP server |
|
||||||
|
| `gitea_mailer_smtp_port` | | Port number for the SMTP server (typically 25, 465, or 587) |
|
||||||
|
| `gitea_mailer_user` | | Username for SMTP authentication |
|
||||||
|
| `gitea_mailer_password` | | Password for SMTP authentication (should be encrypted with Ansible Vault) |
|
||||||
|
| `gitea_mailer_from` | `noreply@{{ gitea_http_domain }}` | Email address used as the sender for all outgoing emails |
|
||||||
|
| `gitea_mailer_subject_prefix` | | Text prepended to all email subject lines |
|
||||||
|
| `gitea_mailer_send_as_plain_text` | `false` | If `true`, sends emails as plain text instead of HTML |
|
||||||
|
| `gitea_mailer_extra_config` | `{}` | Dictionary of additional mailer configuration options |
|
||||||
|
|
||||||
|
## Mirror Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_mirror_enabled` | `true` | Enable repository mirroring functionality |
|
||||||
|
| `gitea_mirror_disable_new_pull` | `false` | If `true`, prevents creation of new pull mirrors (mirroring from external repos) |
|
||||||
|
| `gitea_mirror_disable_new_push` | `false` | If `true`, prevents creation of new push mirrors (mirroring to external repos) |
|
||||||
|
| `gitea_mirror_default_interval` | `8h` | Default synchronization interval for new mirrors |
|
||||||
|
| `gitea_mirror_min_interval` | `10m` | Minimum allowed interval between mirror synchronizations |
|
||||||
|
| `gitea_mirror_extra_config` | `{}` | Dictionary of additional mirror configuration options |
|
||||||
|
|
||||||
|
## Metrics Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_metrics_enabled` | `false` | Enable Prometheus metrics endpoint at `/metrics` |
|
||||||
|
| `gitea_metrics_token` | | Authentication token required to access the metrics endpoint |
|
||||||
|
| `gitea_metrics_extra_config` | `{}` | Dictionary of additional metrics configuration options |
|
||||||
|
|
||||||
|
## API Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_api_enable_swagger` | `true` | Enable Swagger UI for API documentation at `/api/swagger` |
|
||||||
|
| `gitea_api_max_response_items` | `50` | Maximum number of items returned in a single API response page |
|
||||||
|
| `gitea_api_default_paging_num` | `30` | Default number of items per page for API responses |
|
||||||
|
| `gitea_api_extra_config` | `{}` | Dictionary of additional API configuration options |
|
||||||
|
|
||||||
|
## OAuth2 Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_oauth2_enabled` | `true` | Enable OAuth2 provider functionality (allows other apps to use Gitea for authentication) |
|
||||||
|
| `gitea_oauth2_access_token_expiration_time` | `3600` | OAuth2 access token lifetime in seconds (default 1 hour) |
|
||||||
|
| `gitea_oauth2_refresh_token_expiration_time` | `730` | OAuth2 refresh token lifetime in hours (default ~30 days) |
|
||||||
|
| `gitea_oauth2_jwt_signing_algorithm` | `RS256` | Algorithm used to sign JWT tokens: `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, or `ES512` |
|
||||||
|
| `gitea_oauth2_jwt_secret` | | Secret key for signing JWT tokens (auto-generated if not provided) |
|
||||||
|
| `gitea_oauth2_extra_config` | `{}` | Dictionary of additional OAuth2 configuration options |
|
||||||
|
|
||||||
|
## Other Configuration
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_show_footer_version` | `true` | If `true`, displays Gitea version number in the page footer |
|
||||||
|
| `gitea_show_footer_template_load_time` | `true` | If `true`, displays page generation time in the footer |
|
||||||
|
| `gitea_enable_sitemap` | `true` | If `true`, generates XML sitemap at `/sitemap.xml` for search engines |
|
||||||
|
| `gitea_enable_feed` | `true` | If `true`, enables RSS and Atom feeds for repositories and users |
|
||||||
|
| `gitea_other_extra_config` | `{}` | Dictionary of additional miscellaneous configuration options |
|
||||||
|
|
||||||
|
## Additional Configuration
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Not all variables that Gitea supports have been implemented yet. Read the following secion to add additional configuration options.
|
||||||
|
|
||||||
|
| Variable Name | Default Value | Description |
|
||||||
|
|---------------|---------------|-------------|
|
||||||
|
| `gitea_extra_config` | `{}` | Dictionary of any additional environment variables to pass to Gitea; consult the [Gitea configuration cheat sheet](https://docs.gitea.com/administration/config-cheat-sheet) for available options |
|
||||||
|
|
||||||
|
### Example: Using `gitea_extra_config`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
gitea_extra_config:
|
||||||
|
GITEA__webhook__ALLOWED_HOST_LIST: "external"
|
||||||
|
GITEA__webhook__SKIP_TLS_VERIFY: "false"
|
||||||
|
GITEA__cron__ENABLED: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Understanding Extra Configuration Variables
|
||||||
|
|
||||||
|
Many configuration sections include an `*_extra_config` variable (e.g., `gitea_server_extra_config`, `gitea_security_extra_config`, etc.). These variables allow you to add additional Gitea configuration options that aren't explicitly defined as separate variables in this role.
|
||||||
|
|
||||||
|
### How Extra Config Variables Work
|
||||||
|
|
||||||
|
Each `*_extra_config` variable is a dictionary that gets merged into the corresponding section of the Gitea configuration. The role converts these dictionaries into the appropriate environment variable format that Gitea expects.
|
||||||
|
|
||||||
|
### Naming Convention
|
||||||
|
|
||||||
|
Gitea uses environment variables with a specific naming pattern:
|
||||||
|
```
|
||||||
|
GITEA__<section>__<key>
|
||||||
|
```
|
||||||
|
|
||||||
|
When you use an `*_extra_config` variable, the role automatically handles the section name for you. You only need to provide the key-value pairs.
|
||||||
|
|
||||||
|
### Available Extra Config Variables
|
||||||
|
|
||||||
|
| Variable | Maps to Gitea Section |
|
||||||
|
|----------|----------------------|
|
||||||
|
| `gitea_server_extra_config` | `[server]` |
|
||||||
|
| `gitea_security_extra_config` | `[security]` |
|
||||||
|
| `gitea_service_extra_config` | `[service]` |
|
||||||
|
| `gitea_repository_extra_config` | `[repository]` |
|
||||||
|
| `gitea_ui_extra_config` | `[ui]` |
|
||||||
|
| `gitea_indexer_extra_config` | `[indexer]` |
|
||||||
|
| `gitea_packages_extra_config` | `[packages]` |
|
||||||
|
| `gitea_actions_extra_config` | `[actions]` |
|
||||||
|
| `gitea_log_extra_config` | `[log]` |
|
||||||
|
| `gitea_mailer_extra_config` | `[mailer]` |
|
||||||
|
| `gitea_mirror_extra_config` | `[mirror]` |
|
||||||
|
| `gitea_metrics_extra_config` | `[metrics]` |
|
||||||
|
| `gitea_api_extra_config` | `[api]` |
|
||||||
|
| `gitea_oauth2_extra_config` | `[oauth2]` |
|
||||||
|
| `gitea_other_extra_config` | `[other]` |
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
#### Adding Server Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
gitea_server_extra_config:
|
||||||
|
OFFLINE_MODE: true
|
||||||
|
DISABLE_ROUTER_LOG: false
|
||||||
|
ENABLE_GZIP: true
|
||||||
|
```
|
||||||
|
|
||||||
|
This translates to these environment variables:
|
||||||
|
```
|
||||||
|
GITEA__server__OFFLINE_MODE=true
|
||||||
|
GITEA__server__DISABLE_ROUTER_LOG=false
|
||||||
|
GITEA__server__ENABLE_GZIP=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Using gitea_extra_config for Any Section
|
||||||
|
|
||||||
|
If you need to configure a section that doesn't have a dedicated `*_extra_config` variable, or want to set options across multiple sections, use `gitea_extra_config`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
gitea_extra_config:
|
||||||
|
# Webhook configuration
|
||||||
|
GITEA__webhook__ALLOWED_HOST_LIST: "external"
|
||||||
|
GITEA__webhook__SKIP_TLS_VERIFY: "false"
|
||||||
|
|
||||||
|
# Cron configuration
|
||||||
|
GITEA__cron__ENABLED: "true"
|
||||||
|
GITEA__cron_DOT_update_checker__ENABLED: "false"
|
||||||
|
|
||||||
|
# Git configuration
|
||||||
|
GITEA__git__DISABLE_DIFF_HIGHLIGHT: "false"
|
||||||
|
GITEA__git__timeout__DEFAULT: "360"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Finding Available Options
|
||||||
|
|
||||||
|
For a complete list of available configuration options, refer to the official [Gitea Configuration Cheat Sheet](https://docs.gitea.com/administration/config-cheat-sheet).
|
||||||
|
|
||||||
|
### Important Notes
|
||||||
|
|
||||||
|
1. **Values**: All values in `*_extra_config` dictionaries should be strings, numbers, or booleans.
|
||||||
|
|
||||||
|
2. **Priority**: Variables defined in `*_extra_config` can override the explicitly defined role variables if they conflict.
|
||||||
|
|
||||||
|
3. **Validation**: The role does not validate extra configuration options. Ensure you're using valid Gitea configuration keys by consulting the official documentation.
|
||||||
|
|
||||||
|
# License
|
||||||
|
MIT License
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
---
|
||||||
|
app_name: gitea
|
||||||
|
|
||||||
|
# User configuration. Note that if using rootless, the uid and gid must be 1000
|
||||||
|
gitea_uid: 1000
|
||||||
|
gitea_gid: 1000
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
gitea_container_name: "{{ app_name | default('gitea') }}"
|
||||||
|
gitea_container_version: latest-rootless
|
||||||
|
gitea_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
gitea_http_port: 3000
|
||||||
|
gitea_ssh_port: 2222
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
gitea_data_path: "{{ app_dir }}/data"
|
||||||
|
gitea_config_path: "{{ app_dir }}/config"
|
||||||
|
gitea_log_path: "{{ app_dir }}/log"
|
||||||
|
gitea_users: []
|
||||||
|
# gitea_users:
|
||||||
|
# - username: someuser
|
||||||
|
# email: user@example.com
|
||||||
|
# password: somepass # Should be a vault secret
|
||||||
|
# admin: true
|
||||||
|
# must_change_password: true
|
||||||
|
# state: present # `absent` if you want to delete this user
|
||||||
|
|
||||||
|
gitea_runners: []
|
||||||
|
# - name: <runner-name>
|
||||||
|
# data_mount: ./runners/main_runner
|
||||||
|
# registration_token: <token>
|
||||||
|
# cache_enabled: true
|
||||||
|
# cache_port: <port> # Use a unique port
|
||||||
|
|
||||||
|
gitea_runner_global_registration_token: ""
|
||||||
|
gitea_runner_image: gitea/act_runner
|
||||||
|
gitea_runner_container_version: latest-dind-rootless
|
||||||
|
gitea_runner_restart_policy: "{{ gitea_restart_policy }}"
|
||||||
|
|
||||||
|
# Fail2Ban vars
|
||||||
|
gitea_fail2ban_enabled: false
|
||||||
|
gitea_fail2ban_jail_maxretry: 10
|
||||||
|
gitea_fail2ban_jail_findtime: 3600
|
||||||
|
gitea_fail2ban_jail_bantime: 900
|
||||||
|
gitea_fail2ban_jail_action: 'iptables-allports[chain="FORWARD"]'
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
|
||||||
|
# Overall (DEFAULT)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#overall-default
|
||||||
|
gitea_app_name: "Gitea"
|
||||||
|
gitea_user: "gitea"
|
||||||
|
gitea_run_mode: "prod"
|
||||||
|
gitea_fqdn: "localhost"
|
||||||
|
|
||||||
|
# Repository Configuration
|
||||||
|
# ->
|
||||||
|
gitea_repo_force_private: false
|
||||||
|
gitea_repo_default_private: 'last'
|
||||||
|
gitea_repo_default_push_create_private: true
|
||||||
|
gitea_repo_preferred_licenses: 'Apache License 2.0,MIT License'
|
||||||
|
gitea_repo_disable_http_git: false
|
||||||
|
gitea_repo_disable_migrations: false
|
||||||
|
gitea_repo_disable_stars: false
|
||||||
|
gitea_repo_default_branch: 'main'
|
||||||
|
gitea_repository_extra_config: {}
|
||||||
|
|
||||||
|
|
||||||
|
# CORS Configuration
|
||||||
|
# ->
|
||||||
|
gitea_cors_enabled: false
|
||||||
|
gitea_cors_allowed_domains: '*'
|
||||||
|
gitea_cors_allowed_methods: 'GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS'
|
||||||
|
gitea_cors_max_age: '10m'
|
||||||
|
gitea_cors_allowed_credentials: false
|
||||||
|
gitea_cors_headers: 'Content-Type,User-Agent'
|
||||||
|
gitea_cors_x_frame_options: 'SAMEORIGIN'
|
||||||
|
|
||||||
|
# UI Configuration
|
||||||
|
# ->
|
||||||
|
gitea_ui_default_theme: "gitea-auto"
|
||||||
|
gitea_ui_themes: ""
|
||||||
|
gitea_ui_show_user_email: true
|
||||||
|
gitea_ui_show_full_name: false
|
||||||
|
gitea_ui_extra_config: {}
|
||||||
|
|
||||||
|
# UI Meta Configuration
|
||||||
|
# ->
|
||||||
|
gitea_ui_meta_author: 'Gitea - Git with a cup of tea'
|
||||||
|
gitea_ui_meta_description: 'Gitea (Git with a cup of tea) is a painless self-hosted Git service written in Go'
|
||||||
|
gitea_ui_meta_keywords: 'go,git,self-hosted,gitea'
|
||||||
|
|
||||||
|
# Server (server)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#server-server
|
||||||
|
gitea_protocol: "http"
|
||||||
|
gitea_http_domain: "{{ gitea_fqdn }}"
|
||||||
|
gitea_root_url: "{{ gitea_protocol }}://{{ gitea_fqdn }}"
|
||||||
|
gitea_http_listen: "127.0.0.1"
|
||||||
|
gitea_internal_http_port: 3000
|
||||||
|
gitea_internal_ssh_port: 2222
|
||||||
|
gitea_ssh_listen: "0.0.0.0"
|
||||||
|
gitea_start_ssh: true
|
||||||
|
gitea_ssh_domain: "{{ gitea_http_domain }}"
|
||||||
|
gitea_landing_page: 'home'
|
||||||
|
gitea_server_extra_config: {}
|
||||||
|
|
||||||
|
# Security (security)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#security-security
|
||||||
|
gitea_secret_key: ""
|
||||||
|
gitea_internal_token: ""
|
||||||
|
gitea_install_lock: false
|
||||||
|
gitea_disable_git_hooks: true
|
||||||
|
gitea_disable_webhooks: false
|
||||||
|
gitea_reverse_proxy_limit: 1
|
||||||
|
gitea_reverse_proxy_trusted_proxies: "127.0.0.0/8,::1/128"
|
||||||
|
gitea_password_complexity: "off"
|
||||||
|
gitea_password_min_length: 8
|
||||||
|
gitea_password_check_pwn: false
|
||||||
|
gitea_2fa: ""
|
||||||
|
gitea_login_remember_days: 31
|
||||||
|
gitea_cookie_remember_name: "gitea_incredible"
|
||||||
|
gitea_security_extra_config: {}
|
||||||
|
|
||||||
|
# Service (service)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#service-service
|
||||||
|
gitea_disable_registration: false
|
||||||
|
gitea_register_email_confirm: false
|
||||||
|
gitea_register_manual_confirm: false
|
||||||
|
gitea_require_signin_view: false
|
||||||
|
gitea_enable_notify_mail: false
|
||||||
|
gitea_enable_captcha: false
|
||||||
|
gitea_require_captcha_for_login: false
|
||||||
|
gitea_captcha_type: image
|
||||||
|
gitea_show_registration_button: true
|
||||||
|
gitea_default_keep_email_private: false
|
||||||
|
gitea_default_allow_create_organization: true
|
||||||
|
gitea_default_user_is_restricted: false
|
||||||
|
gitea_default_user_visibility: public
|
||||||
|
gitea_default_org_visibility: public
|
||||||
|
gitea_default_org_member_visible: false
|
||||||
|
gitea_allow_only_internal_registration: false
|
||||||
|
gitea_allow_only_external_registration: false
|
||||||
|
gitea_email_domain_allowlist: ""
|
||||||
|
gitea_email_domain_blocklist: ""
|
||||||
|
gitea_no_reply_address: ""
|
||||||
|
gitea_enable_user_heatmap: true
|
||||||
|
gitea_enable_timetracking: true
|
||||||
|
gitea_auto_watch_new_repos: true
|
||||||
|
gitea_auto_watch_on_changes: false
|
||||||
|
gitea_show_milestones_dashboard_page: true
|
||||||
|
gitea_service_extra_config: {}
|
||||||
|
|
||||||
|
# Indexer (indexer)
|
||||||
|
# -> https://docs.gitea.com/administration/config-cheat-sheet#indexer-indexer
|
||||||
|
gitea_issue_indexer_type: 'bleve'
|
||||||
|
gitea_issue_indexer_connection_string: ''
|
||||||
|
gitea_issue_indexer_name: 'gitea_issues'
|
||||||
|
gitea_issue_indexer_path: 'indexers/issues.bleve'
|
||||||
|
gitea_repo_indexer_enabled: false
|
||||||
|
gitea_repo_indexer_repo_types: 'sources,forks,mirrors,templates'
|
||||||
|
gitea_repo_indexer_type: 'bleve'
|
||||||
|
gitea_repo_indexer_path: 'indexers/repos.bleve'
|
||||||
|
gitea_repo_indexer_connection_string: ''
|
||||||
|
gitea_repo_indexer_name: 'gitea_codes'
|
||||||
|
gitea_repo_indexer_include: ''
|
||||||
|
gitea_repo_indexer_exclude: ''
|
||||||
|
gitea_repo_indexer_exclude_vendored: true
|
||||||
|
gitea_repo_indexer_max_file_size: 1048576
|
||||||
|
gitea_indexer_startup_timeout: '30s'
|
||||||
|
gitea_indexer_extra_config: {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Packages (packages)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#packages-packages
|
||||||
|
gitea_packages_enabled: true
|
||||||
|
gitea_packages_extra_config: {}
|
||||||
|
|
||||||
|
# Actions (actions)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#actions-actions
|
||||||
|
gitea_actions_enabled: false
|
||||||
|
gitea_actions_default_actions_url: github
|
||||||
|
gitea_actions_extra_config: {}
|
||||||
|
|
||||||
|
# Log (log)
|
||||||
|
# -> https://docs.gitea.com/next/administration/config-cheat-sheet#log-log
|
||||||
|
gitea_log_root_path: ""
|
||||||
|
gitea_log_mode: console
|
||||||
|
gitea_log_level: Info
|
||||||
|
gitea_enable_ssh_log: false
|
||||||
|
gitea_log_extra_config: {}
|
||||||
|
|
||||||
|
# Mailer (mailer)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#mailer-mailer
|
||||||
|
gitea_mailer_enabled: false
|
||||||
|
gitea_mailer_protocol: "" # smtp, smtps, smtp+starttls, smtp+unix, sendmail, dummy
|
||||||
|
gitea_mailer_smtp_addr: ""
|
||||||
|
gitea_mailer_smtp_port: ""
|
||||||
|
gitea_mailer_user: ""
|
||||||
|
gitea_mailer_password: ""
|
||||||
|
gitea_mailer_from: "noreply@{{ gitea_http_domain }}"
|
||||||
|
gitea_mailer_subject_prefix: ""
|
||||||
|
gitea_mailer_send_as_plain_text: false
|
||||||
|
gitea_mailer_extra_config: {}
|
||||||
|
|
||||||
|
# Mirror (mirror)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#mirror-mirror
|
||||||
|
gitea_mirror_enabled: true
|
||||||
|
gitea_mirror_disable_new_pull: false
|
||||||
|
gitea_mirror_disable_new_push: false
|
||||||
|
gitea_mirror_default_interval: 8h
|
||||||
|
gitea_mirror_min_interval: 10m
|
||||||
|
gitea_mirror_extra_config: {}
|
||||||
|
|
||||||
|
# Other (other)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#other-other
|
||||||
|
gitea_show_footer_version: true
|
||||||
|
gitea_show_footer_template_load_time: true
|
||||||
|
gitea_enable_sitemap: true
|
||||||
|
gitea_enable_feed: true
|
||||||
|
gitea_other_extra_config: {}
|
||||||
|
|
||||||
|
# Metrics (metrics)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#metrics-metrics
|
||||||
|
gitea_metrics_enabled: false
|
||||||
|
gitea_metrics_token: ""
|
||||||
|
gitea_metrics_extra_config: {}
|
||||||
|
|
||||||
|
# API (api)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#api-api
|
||||||
|
gitea_api_enable_swagger: true
|
||||||
|
gitea_api_max_response_items: 50
|
||||||
|
gitea_api_default_paging_num: 30
|
||||||
|
gitea_api_extra_config: {}
|
||||||
|
|
||||||
|
# OAuth2 (oauth2)
|
||||||
|
# -> https://docs.gitea.io/en-us/config-cheat-sheet/#oauth2-oauth2
|
||||||
|
gitea_oauth2_enabled: true
|
||||||
|
gitea_oauth2_access_token_expiration_time: 3600
|
||||||
|
gitea_oauth2_refresh_token_expiration_time: 730
|
||||||
|
gitea_oauth2_jwt_signing_algorithm: RS256
|
||||||
|
gitea_oauth2_jwt_secret: ""
|
||||||
|
gitea_oauth2_extra_config: {}
|
||||||
|
|
||||||
|
# A dictionary of additional environment variables
|
||||||
|
# Read the cheat sheet before adding configurations https://docs.gitea.com/administration/config-cheat-sheet
|
||||||
|
gitea_extra_config: {}
|
||||||
|
# ENV_VAR_KEY: value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: "Restart fail2ban"
|
||||||
|
become: true
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: fail2ban
|
||||||
|
state: restarted
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
install_date: Tue Dec 2 19:10:42 2025
|
||||||
|
version: ''
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
app_role_name: gitea
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Ansible role to configure and deploy Gitea in Docker, with optional support for runners.
|
||||||
|
license: MIT License
|
||||||
|
min_ansible_version: 2.11
|
||||||
|
platforms:
|
||||||
|
- name: Debian
|
||||||
|
versions: all
|
||||||
|
- name: Ubuntu
|
||||||
|
version: all
|
||||||
|
galaxy_tags:
|
||||||
|
- gitea
|
||||||
|
- act_runner
|
||||||
|
- git
|
||||||
|
- gitserver
|
||||||
|
- selfhosted
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: gitea
|
||||||
|
app_compose_validate: false
|
||||||
|
app_compose_start: false
|
||||||
|
app_uid: "{{ gitea_uid }}"
|
||||||
|
app_gid: "{{ gitea_gid }}"
|
||||||
|
app_extra_templates:
|
||||||
|
- src: env.j2
|
||||||
|
dest: "{{ app_dir }}/.env"
|
||||||
|
# Directory structure
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ gitea_data_path }}"
|
||||||
|
- "{{ gitea_config_path }}"
|
||||||
|
- "{{ gitea_log_path }}"
|
||||||
|
|
||||||
|
# Backup configuration
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ gitea_data_path }}"
|
||||||
|
- "{{ gitea_config_path }}"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Get host IP
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
gitea_host_ip: "{{ ansible_default_ipv4.address }}"
|
||||||
|
|
||||||
|
- name: Create data directories for runners
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ app_dir }}/{{ item.data_mount }}"
|
||||||
|
state: directory
|
||||||
|
mode: "{{ app_permission_mode }}"
|
||||||
|
owner: "{{ app_uid }}"
|
||||||
|
group: "{{ app_gid }}"
|
||||||
|
loop: "{{ gitea_runners }}"
|
||||||
|
|
||||||
|
- name: Create configuration files for each runner
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: actions/config.yaml.j2
|
||||||
|
dest: "{{ app_dir }}/{{ item.config_file_mount }}"
|
||||||
|
mode: "{{ app_permission_mode }}"
|
||||||
|
owner: "{{ app_uid }}"
|
||||||
|
group: "{{ app_gid }}"
|
||||||
|
loop: "{{ gitea_runners }}"
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy optional fail2ban rules
|
||||||
|
ansible.builtin.include_tasks: setup-fail2ban.yaml
|
||||||
|
when: gitea_fail2ban_enabled | bool
|
||||||
|
|
||||||
|
- name: Generate Gitea configuration files
|
||||||
|
ansible.builtin.include_tasks: generate-config.yaml
|
||||||
|
|
||||||
|
- name: Create or remove Gitea users
|
||||||
|
ansible.builtin.include_tasks: manage_users.yaml
|
||||||
|
when: gitea_users | length > 0
|
||||||
|
|
||||||
|
- name: Start Docker Compose stack after configuration
|
||||||
|
ansible.builtin.include_tasks: "{{ app_roles_path }}/docker_compose_app/tasks/manage_compose.yaml"
|
||||||
|
vars:
|
||||||
|
app_compose_start: true
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
- name: Get list of users
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ gitea_container_name }}"
|
||||||
|
command: /bin/bash -c "gitea admin user list"
|
||||||
|
register: user_list
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
when: gitea_users | length > 0
|
||||||
|
|
||||||
|
- name: Extract existing usernames
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
gitea_existing_users: "{{ user_list.stdout_lines[1:] | map('regex_replace', '^\\d+\\s+(\\S+)\\s+.*$', '\\1') | list | default([]) }}"
|
||||||
|
when:
|
||||||
|
- gitea_users | length > 0
|
||||||
|
- user_list.stdout_lines | default([]) | length > 1
|
||||||
|
|
||||||
|
- name: Create Gitea users
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ gitea_container_name }}"
|
||||||
|
command: >
|
||||||
|
/bin/bash -c "gitea admin user create
|
||||||
|
--username {{ user.username }}
|
||||||
|
--email {{ user.email }}
|
||||||
|
--password {{ user.password }}
|
||||||
|
--must-change-password={{ user.must_change_password | default(false) }}
|
||||||
|
--admin={{ user.admin | default(false) }}"
|
||||||
|
register: _gitea_user_result
|
||||||
|
failed_when:
|
||||||
|
- '"successfully created" not in _gitea_user_result.stdout'
|
||||||
|
changed_when:
|
||||||
|
- '"successfully created!" in _gitea_user_result.stdout'
|
||||||
|
when:
|
||||||
|
- user.username not in gitea_existing_users | default([]) and user.state | default('present') == 'present'
|
||||||
|
loop: "{{ gitea_users }}"
|
||||||
|
loop_control:
|
||||||
|
label: "user={{ user.username }}"
|
||||||
|
loop_var: user
|
||||||
|
# no_log: true # Avoid logging passwords
|
||||||
|
|
||||||
|
|
||||||
|
- name: Remove gitea users
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ gitea_container_name }}"
|
||||||
|
command: >
|
||||||
|
/bin/bash -c "gitea admin user delete
|
||||||
|
--username {{ user.username }}
|
||||||
|
--email {{ user.email }}"
|
||||||
|
register: _gitea_user_del_result
|
||||||
|
failed_when:
|
||||||
|
- '"error" in _gitea_user_del_result.stdout'
|
||||||
|
changed_when: "user.username in gitea_existing_users"
|
||||||
|
when: "user.username in gitea_existing_users | default([]) and user.state | default('present') == 'absent'"
|
||||||
|
loop: "{{ gitea_users }}"
|
||||||
|
loop_control:
|
||||||
|
label: "user={{ user.username }}"
|
||||||
|
loop_var: user
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Gather installed packages for checks later on
|
||||||
|
ansible.builtin.package_facts:
|
||||||
|
manager: "auto"
|
||||||
|
|
||||||
|
- name: Warn if fail2ban is not installed
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "the package fail2ban is not installed. no fail2ban filters deployed."
|
||||||
|
when: "'fail2ban' not in ansible_facts.packages"
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Install fail2ban filter
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: fail2ban/filter.conf.j2
|
||||||
|
dest: /etc/fail2ban/filter.d/gitea.local
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0444"
|
||||||
|
notify: "Restart fail2ban"
|
||||||
|
when: "'fail2ban' in ansible_facts.packages"
|
||||||
|
|
||||||
|
- name: Install fail2ban jail for logins over HTTP(S)
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
gitea_fail2ban_filter: gitea
|
||||||
|
gitea_fail2ban_port: "http,https,{{ gitea_ssh_port }}"
|
||||||
|
gitea_fail2ban_jail_name: gitea-docker
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: fail2ban/jail.conf.j2
|
||||||
|
dest: /etc/fail2ban/jail.d/gitea.local
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0444"
|
||||||
|
notify: "Restart fail2ban"
|
||||||
|
when: "'fail2ban' in ansible_facts.packages"
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# Example configuration file, it's safe to copy this as the default config file without any modification.
|
||||||
|
# https://gitea.com/gitea/act_runner/src/branch/main/internal/pkg/config/config.example.yaml
|
||||||
|
|
||||||
|
# You don't have to copy this file to your instance,
|
||||||
|
# just run `./act_runner generate-config > config.yaml` to generate a config file.
|
||||||
|
|
||||||
|
log:
|
||||||
|
# The level of logging, can be trace, debug, info, warn, error, fatal
|
||||||
|
level: info
|
||||||
|
|
||||||
|
runner:
|
||||||
|
# Where to store the registration result.
|
||||||
|
file: .runner
|
||||||
|
# Execute how many tasks concurrently at the same time.
|
||||||
|
capacity: 1
|
||||||
|
# Extra environment variables to run jobs.
|
||||||
|
envs:
|
||||||
|
# A_TEST_ENV_NAME_1: a_test_env_value_1
|
||||||
|
# A_TEST_ENV_NAME_2: a_test_env_value_2
|
||||||
|
# Extra environment variables to run jobs from a file.
|
||||||
|
# It will be ignored if it's empty or the file doesn't exist.
|
||||||
|
env_file: .env
|
||||||
|
# The timeout for a job to be finished.
|
||||||
|
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
|
||||||
|
# So the job could be stopped by the Gitea instance if its timeout is shorter than this.
|
||||||
|
timeout: 3h
|
||||||
|
# The timeout for the runner to wait for running jobs to finish when shutting down.
|
||||||
|
# Any running jobs that haven't finished after this timeout will be cancelled.
|
||||||
|
shutdown_timeout: 0s
|
||||||
|
# Whether skip verifying the TLS certificate of the Gitea instance.
|
||||||
|
insecure: false
|
||||||
|
# The timeout for fetching the job from the Gitea instance.
|
||||||
|
fetch_timeout: 5s
|
||||||
|
# The interval for fetching the job from the Gitea instance.
|
||||||
|
fetch_interval: 2s
|
||||||
|
# The github_mirror of a runner is used to specify the mirror address of the github that pulls the action repository.
|
||||||
|
# It works when something like `uses: actions/checkout@v4` is used and DEFAULT_ACTIONS_URL is set to github,
|
||||||
|
# and github_mirror is not empty. In this case,
|
||||||
|
# it replaces https://github.com with the value here, which is useful for some special network environments.
|
||||||
|
github_mirror: ''
|
||||||
|
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
|
||||||
|
# Like: "macos-arm64:host" or "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
|
||||||
|
# Find more images provided by Gitea at https://gitea.com/gitea/runner-images .
|
||||||
|
# If it's empty when registering, it will ask for inputting labels.
|
||||||
|
# If it's empty when execute `daemon`, will use labels in `.runner` file.
|
||||||
|
labels:
|
||||||
|
- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
|
||||||
|
- "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04"
|
||||||
|
- "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
|
||||||
|
|
||||||
|
cache:
|
||||||
|
# Enable cache server to use actions/cache.
|
||||||
|
enabled: {{ item.cache_enabled | bool | lower }}
|
||||||
|
# The directory to store the cache data.
|
||||||
|
# If it's empty, the cache data will be stored in $HOME/.cache/actcache.
|
||||||
|
dir: ""
|
||||||
|
# The host of the cache server.
|
||||||
|
# It's not for the address to listen, but the address to connect from job containers.
|
||||||
|
# So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
|
||||||
|
host: {{ gitea_host_ip }}
|
||||||
|
# The port of the cache server.
|
||||||
|
# 0 means to use a random available port.
|
||||||
|
port: {{ item.cache_port }}
|
||||||
|
# The external cache server URL. Valid only when enable is true.
|
||||||
|
# If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
|
||||||
|
# The URL should generally end with "/".
|
||||||
|
external_server: ""
|
||||||
|
|
||||||
|
container:
|
||||||
|
# Specifies the network to which the container will connect.
|
||||||
|
# Could be host, bridge or the name of a custom network.
|
||||||
|
# If it's empty, act_runner will create a network automatically.
|
||||||
|
network: ""
|
||||||
|
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
|
||||||
|
privileged: false
|
||||||
|
# Any other options to be used when the container is started (e.g., --add-host=my.gitea.url:host-gateway).
|
||||||
|
options:
|
||||||
|
# The parent directory of a job's working directory.
|
||||||
|
# NOTE: There is no need to add the first '/' of the path as act_runner will add it automatically.
|
||||||
|
# If the path starts with '/', the '/' will be trimmed.
|
||||||
|
# For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir
|
||||||
|
# If it's empty, /workspace will be used.
|
||||||
|
workdir_parent:
|
||||||
|
# Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
|
||||||
|
# You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
|
||||||
|
# For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
|
||||||
|
# valid_volumes:
|
||||||
|
# - data
|
||||||
|
# - /src/*.json
|
||||||
|
# If you want to allow any volume, please use the following configuration:
|
||||||
|
# valid_volumes:
|
||||||
|
# - '**'
|
||||||
|
valid_volumes: []
|
||||||
|
# Overrides the docker client host with the specified one.
|
||||||
|
# If it's empty, act_runner will find an available docker host automatically.
|
||||||
|
# If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers.
|
||||||
|
# If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work.
|
||||||
|
docker_host: ""
|
||||||
|
# Pull docker image(s) even if already present
|
||||||
|
force_pull: true
|
||||||
|
# Rebuild docker image(s) even if already present
|
||||||
|
force_rebuild: false
|
||||||
|
# Always require a reachable docker daemon, even if not required by act_runner
|
||||||
|
require_docker: false
|
||||||
|
# Timeout to wait for the docker daemon to be reachable, if docker is required by require_docker or act_runner
|
||||||
|
docker_timeout: 0s
|
||||||
|
|
||||||
|
host:
|
||||||
|
# The parent directory of a job's working directory.
|
||||||
|
# If it's empty, $HOME/.cache/act/ will be used.
|
||||||
|
workdir_parent:
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: docker.gitea.com/gitea:{{ gitea_container_version }}
|
||||||
|
container_name: "{{ gitea_container_name }}"
|
||||||
|
restart: "{{ gitea_restart_policy }}"
|
||||||
|
environment:
|
||||||
|
- USER_UID={{ app_uid }}
|
||||||
|
- USER_GID={{ app_gid }}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- "{{ gitea_data_path }}:/var/lib/gitea"
|
||||||
|
- "{{ gitea_config_path }}:/etc/gitea"
|
||||||
|
- "{{ gitea_log_path }}:/var/log/gitea"
|
||||||
|
- "/etc/timezone:/etc/timezone:ro"
|
||||||
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:{{ gitea_http_port }}:3000"
|
||||||
|
- "0.0.0.0:{{ gitea_ssh_port }}:2222"
|
||||||
|
{% for runner in gitea_runners %}
|
||||||
|
{{ runner.name }}:
|
||||||
|
image: "{{ gitea_runner_image }}:{{ gitea_runner_container_version }}"
|
||||||
|
container_name: "{{ app_name }}-{{ runner.name }}"
|
||||||
|
restart: "{{ gitea_runner_restart_policy }}"
|
||||||
|
privileged: true
|
||||||
|
depends_on:
|
||||||
|
- "{{ gitea_container_name }}"
|
||||||
|
volumes:
|
||||||
|
- {{ runner.config_file_mount }}:/config.yaml
|
||||||
|
- {{ runner.data_mount }}:/data
|
||||||
|
{% if runner.cache_enabled %}
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:{{ runner.cache_port }}:{{ runner.cache_port }}
|
||||||
|
{% endif %}
|
||||||
|
environment:
|
||||||
|
CONFIG_FILE: /config.yaml
|
||||||
|
GITEA_RUNNER_NAME: {{ runner.name }}
|
||||||
|
GITEA_INSTANCE_URL: {{ gitea_root_url }}
|
||||||
|
DOCKER_HOST: "unix:///var/run/user/{{ app_uid }}/docker.sock"
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN: {{ gitea_runner_global_registration_token | default(runner.registration_token) | default('') }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,429 @@
|
|||||||
|
# ============================================
|
||||||
|
# Default Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__DEFAULT__APP_NAME={{ gitea_app_name }}
|
||||||
|
GITEA__DEFAULT__RUN_MODE={{ gitea_run_mode }}
|
||||||
|
GITEA__DEFAULT__RUN_USER={{ gitea_user }}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Server Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__server__PROTOCOL={{ gitea_protocol }}
|
||||||
|
GITEA__server__DOMAIN={{ gitea_http_domain }}
|
||||||
|
GITEA__server__ROOT_URL={{ gitea_root_url }}
|
||||||
|
GITEA__server__HTTP_ADDR={{ gitea_http_listen }}
|
||||||
|
GITEA__server__HTTP_PORT={{ gitea_internal_http_port }}
|
||||||
|
GITEA__server__SSH_PORT={{ gitea_internal_ssh_port }}
|
||||||
|
GITEA__server__SSH_LISTEN_HOST={{ gitea_ssh_listen }}
|
||||||
|
GITEA__server__START_SSH_SERVER={{ gitea_start_ssh | bool | lower }}
|
||||||
|
GITEA__server__SSH_DOMAIN={{ gitea_ssh_domain }}
|
||||||
|
GITEA__server__LANDING_PAGE={{ gitea_landing_page }}
|
||||||
|
|
||||||
|
{% if gitea_server_extra_config %}
|
||||||
|
# Additional Server Configuration
|
||||||
|
{% for item in gitea_server_extra_config | dict2items %}
|
||||||
|
GITEA__server__{{ item.key }}={{ item.value }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Service Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__service__DISABLE_REGISTRATION={{ gitea_disable_registration | bool | lower }}
|
||||||
|
GITEA__service__REGISTER_EMAIL_CONFIRM={{ gitea_register_email_confirm | bool | lower }}
|
||||||
|
GITEA__service__REGISTER_MANUAL_CONFIRM={{ gitea_register_manual_confirm | bool | lower }}
|
||||||
|
GITEA__service__REQUIRE_SIGNIN_VIEW={{ gitea_require_signin_view | bool | lower }}
|
||||||
|
GITEA__service__ENABLE_NOTIFY_MAIL={{ gitea_enable_notify_mail | bool | lower }}
|
||||||
|
GITEA__service__ENABLE_CAPTCHA={{ gitea_enable_captcha | bool | lower }}
|
||||||
|
{% if gitea_enable_captcha %}
|
||||||
|
GITEA__service__REQUIRE_CAPTCHA_FOR_LOGIN={{ gitea_require_captcha_for_login }}
|
||||||
|
GITEA__service__CAPTCHA_TYPE={{ gitea_captcha_type }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__service__SHOW_REGISTRATION_BUTTON={{ gitea_show_registration_button | bool | lower }}
|
||||||
|
GITEA__service__DEFAULT_KEEP_EMAIL_PRIVATE={{ gitea_default_keep_email_private | bool | lower }}
|
||||||
|
GITEA__service__DEFAULT_ALLOW_CREATE_ORGANIZATION={{ gitea_default_allow_create_organization | bool | lower }}
|
||||||
|
GITEA__service__DEFAULT_USER_IS_RESTRICTED={{ gitea_default_user_is_restricted | bool | lower }}
|
||||||
|
GITEA__service__DEFAULT_USER_VISIBILITY={{ gitea_default_user_visibility }}
|
||||||
|
GITEA__service__DEFAULT_ORG_VISIBILITY={{ gitea_default_org_visibility }}
|
||||||
|
GITEA__service__DEFAULT_ORG_MEMBER_VISIBLE={{ gitea_default_org_member_visible | bool | lower }}
|
||||||
|
GITEA__service__ALLOW_ONLY_INTERNAL_REGISTRATION={{ gitea_allow_only_internal_registration | bool | lower }}
|
||||||
|
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION={{ gitea_allow_only_external_registration | bool | lower }}
|
||||||
|
{% if gitea_email_domain_allowlist %}
|
||||||
|
GITEA__service__EMAIL_DOMAIN_ALLOWLIST={{ gitea_email_domain_allowlist }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_email_domain_blocklist %}
|
||||||
|
GITEA__service__EMAIL_DOMAIN_BLOCKLIST={{ gitea_email_domain_blocklist }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_no_reply_address %}
|
||||||
|
GITEA__service__NO_REPLY_ADDRESS={{ gitea_no_reply_address }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__service__ENABLE_USER_HEATMAP={{ gitea_enable_user_heatmap | bool | lower }}
|
||||||
|
GITEA__service__ENABLE_TIMETRACKING={{ gitea_enable_timetracking | bool | lower }}
|
||||||
|
GITEA__service__AUTO_WATCH_NEW_REPOS={{ gitea_auto_watch_new_repos | bool | lower }}
|
||||||
|
GITEA__service__AUTO_WATCH_ON_CHANGES={{ gitea_auto_watch_on_changes | bool | lower }}
|
||||||
|
GITEA__service__SHOW_MILESTONES_DASHBOARD_PAGE={{ gitea_show_milestones_dashboard_page | bool | lower }}
|
||||||
|
|
||||||
|
{% if gitea_service_extra_config %}
|
||||||
|
# Additional Service Configuration
|
||||||
|
{% for item in gitea_service_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__service__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__service__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Security Configuration
|
||||||
|
# ============================================
|
||||||
|
{% if gitea_secret_key %}
|
||||||
|
GITEA__security__SECRET_KEY={{ gitea_secret_key }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_internal_token %}
|
||||||
|
GITEA__security__INTERNAL_TOKEN={{ gitea_internal_token }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__security__INSTALL_LOCK={{ gitea_install_lock | bool | lower }}
|
||||||
|
GITEA__security__DISABLE_GIT_HOOKS={{ gitea_disable_git_hooks | bool | lower }}
|
||||||
|
GITEA__security__DISABLE_WEBHOOKS={{ gitea_disable_webhooks | bool | lower }}
|
||||||
|
GITEA__security__PASSWORD_COMPLEXITY={{ gitea_password_complexity }}
|
||||||
|
GITEA__security__PASSWORD_MIN_LENGTH={{ gitea_password_min_length }}
|
||||||
|
GITEA__security__PASSWORD_CHECK_PWN={{ gitea_password_check_pwn | bool | lower }}
|
||||||
|
{% if gitea_2fa %}
|
||||||
|
GITEA__security__TWO_FACTOR_AUTH={{ gitea_2fa }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__security__LOGIN_REMEMBER_DAYS={{ gitea_login_remember_days }}
|
||||||
|
GITEA__security__COOKIE_REMEMBER_NAME={{ gitea_cookie_remember_name }}
|
||||||
|
|
||||||
|
{% if gitea_security_extra_config %}
|
||||||
|
# Additional Security Configuration
|
||||||
|
{% for item in gitea_security_extra_config | dict2items %}
|
||||||
|
GITEA__security__{{ item.key }}={{ item.value if item.value is not boolean else (item.value | bool | lower) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Repository Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__repository__FORCE_PRIVATE={{ gitea_repo_force_private }}
|
||||||
|
GITEA__repository__DEFAULT_PRIVATE={{ gitea_repo_default_private }}
|
||||||
|
GITEA__repository__DEFAULT_PUSH_CREATE_PRIVATE={{ gitea_repo_default_push_create_private }}
|
||||||
|
GITEA__repository__PREFERRED_LICENSES={{ gitea_repo_preferred_licenses }}
|
||||||
|
GITEA__repository__DISABLE_HTTP_GIT={{ gitea_repo_disable_http_git }}
|
||||||
|
GITEA__repository__DEFAULT_BRANCH={{ gitea_repo_default_branch }}
|
||||||
|
GITEA__repository__DISABLE_STARS={{ gitea_repo_disable_stars }}
|
||||||
|
GITEA__repository__DISABLE_MIGRATIONS={{ gitea_repo_disable_migrations }}
|
||||||
|
|
||||||
|
{% if gitea_repository_extra_config %}
|
||||||
|
# Additional Repository Configuration
|
||||||
|
{% for item in gitea_repository_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__repository__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__repository__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# CORS Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__cors__ENABLED={{ gitea_cors_enabled }}
|
||||||
|
GITEA__cors__ALLOW_DOMAIN={{ gitea_cors_allowed_domains }}
|
||||||
|
GITEA__cors__METHODS={{ gitea_cors_allowed_methods }}
|
||||||
|
GITEA__cors__MAX_AGE={{ gitea_cors_max_age }}
|
||||||
|
GITEA__cors__ALLOW_CREDENTIALS={{ gitea_cors_allowed_credentials | bool | lower }}
|
||||||
|
GITEA__cors__HEADERS={{ gitea_cors_headers }}
|
||||||
|
GITEA__cors__X_FRAME_OPTIONS={{ gitea_cors_x_frame_options }}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# UI Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__ui__DEFAULT_THEME={{ gitea_ui_default_theme }}
|
||||||
|
GITEA__ui__THEMES={{ gitea_ui_themes }}
|
||||||
|
GITEA__ui__SHOW_USER_EMAIL={{ gitea_ui_show_user_email }}
|
||||||
|
GITEA__ui__DEFAULT_SHOW_FULL_NAME={{ gitea_ui_show_full_name }}
|
||||||
|
|
||||||
|
{% if gitea_ui_extra_config %}
|
||||||
|
# Additional UI Configuration
|
||||||
|
{% for item in gitea_ui_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__ui__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__ui__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# UI.meta Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__ui.meta__AUTHOR={{ gitea_ui_meta_author }}
|
||||||
|
GITEA__ui.meta__DESCRIPTION={{ gitea_ui_meta_description }}
|
||||||
|
GITEA__ui.meta__KEYWORDS={{ gitea_ui_meta_keywords }}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Indexer Configuration
|
||||||
|
# ============================================
|
||||||
|
# Issue Indexer
|
||||||
|
GITEA__indexer__ISSUE_INDEXER_TYPE={{ gitea_issue_indexer_type }}
|
||||||
|
{% if gitea_issue_indexer_type in ['elasticsearch', 'meilisearch'] and gitea_issue_indexer_connection_string %}
|
||||||
|
GITEA__indexer__ISSUE_INDEXER_CONN_STR={{ gitea_issue_indexer_connection_string }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_issue_indexer_type in ['elasticsearch', 'meilisearch'] and gitea_issue_indexer_name %}
|
||||||
|
GITEA__indexer__ISSUE_INDEXER_NAME={{ gitea_issue_indexer_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_issue_indexer_type == 'bleve' and gitea_issue_indexer_path %}
|
||||||
|
GITEA__indexer__ISSUE_INDEXER_PATH={{ gitea_issue_indexer_path }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Repository Indexer
|
||||||
|
GITEA__indexer__REPO_INDEXER_ENABLED={{ gitea_repo_indexer_enabled | bool | lower }}
|
||||||
|
{% if gitea_repo_indexer_enabled %}
|
||||||
|
{% if gitea_repo_indexer_repo_types %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_REPO_TYPES={{ gitea_repo_indexer_repo_types }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_TYPE={{ gitea_repo_indexer_type }}
|
||||||
|
{% if gitea_repo_indexer_type == 'bleve' and gitea_repo_indexer_path %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_PATH={{ gitea_repo_indexer_path }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_repo_indexer_type == 'elasticsearch' and gitea_repo_indexer_connection_string %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_CONN_STR={{ gitea_repo_indexer_connection_string }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_repo_indexer_type == 'elasticsearch' and gitea_repo_indexer_name %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_NAME={{ gitea_repo_indexer_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_repo_indexer_include %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_INCLUDE={{ gitea_repo_indexer_include }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_repo_indexer_exclude %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_EXCLUDE={{ gitea_repo_indexer_exclude }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__indexer__REPO_INDEXER_EXCLUDE_VENDORED={{ gitea_repo_indexer_exclude_vendored | bool | lower }}
|
||||||
|
GITEA__indexer__MAX_FILE_SIZE={{ gitea_repo_indexer_max_file_size }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_indexer_startup_timeout %}
|
||||||
|
GITEA__indexer__STARTUP_TIMEOUT={{ gitea_indexer_startup_timeout }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_indexer_extra_config %}
|
||||||
|
# Additional Indexer Configuration
|
||||||
|
{% for item in gitea_indexer_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__indexer__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__indexer__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Packages Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__packages__ENABLED={{ gitea_packages_enabled | bool | lower }}
|
||||||
|
|
||||||
|
{% if gitea_packages_extra_config %}
|
||||||
|
# Additional Packages Configuration
|
||||||
|
{% for item in gitea_packages_extra_config | dict2items %}
|
||||||
|
GITEA__packages__{{ item.key }}={{ item.value if item.value is not boolean else (item.value | bool | lower) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Actions Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__actions__ENABLED={{ gitea_actions_enabled | bool | lower }}
|
||||||
|
{% if gitea_actions_enabled %}
|
||||||
|
GITEA__actions__DEFAULT_ACTIONS_URL={{ gitea_actions_default_actions_url }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_runner_global_registration_token %}
|
||||||
|
GITEA_RUNNER_REGISTRATION_TOKEN={{ gitea_runner_global_registration_token }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_actions_extra_config %}
|
||||||
|
# Additional Actions Configuration
|
||||||
|
{% for item in gitea_actions_extra_config | dict2items %}
|
||||||
|
GITEA__actions__{{ item.key }}={{ item.value if item.value is not boolean else (item.value | bool | lower) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Log Configuration
|
||||||
|
# ============================================
|
||||||
|
{% if gitea_log_root_path %}
|
||||||
|
GITEA__log__ROOT_PATH={{ gitea_log_root_path }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__log__MODE={{ gitea_log_mode }}
|
||||||
|
GITEA__log__LEVEL={{ gitea_log_level }}
|
||||||
|
|
||||||
|
{% if gitea_log_extra_config %}
|
||||||
|
# Additional Log Configuration
|
||||||
|
{% for item in gitea_log_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__log__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__log__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Mailer Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__mailer__ENABLED={{ gitea_mailer_enabled | bool | lower }}
|
||||||
|
{% if gitea_mailer_enabled %}
|
||||||
|
{% if gitea_mailer_protocol %}
|
||||||
|
GITEA__mailer__PROTOCOL={{ gitea_mailer_protocol }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_smtp_addr %}
|
||||||
|
GITEA__mailer__SMTP_ADDR={{ gitea_mailer_smtp_addr }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_smtp_port %}
|
||||||
|
GITEA__mailer__SMTP_PORT={{ gitea_mailer_smtp_port }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_user %}
|
||||||
|
GITEA__mailer__USER={{ gitea_mailer_user }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_password %}
|
||||||
|
GITEA__mailer__PASSWD={{ gitea_mailer_password }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_from %}
|
||||||
|
GITEA__mailer__FROM={{ gitea_mailer_from }}
|
||||||
|
{% endif %}
|
||||||
|
{% if gitea_mailer_subject_prefix %}
|
||||||
|
GITEA__mailer__SUBJECT_PREFIX={{ gitea_mailer_subject_prefix }}
|
||||||
|
{% endif %}
|
||||||
|
GITEA__mailer__SEND_AS_PLAIN_TEXT={{ gitea_mailer_send_as_plain_text | bool | lower }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_mailer_extra_config %}
|
||||||
|
# Additional Mailer Configuration
|
||||||
|
{% for item in gitea_mailer_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__mailer__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__mailer__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Mirror Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__mirror__ENABLED={{ gitea_mirror_enabled | bool | lower }}
|
||||||
|
GITEA__mirror__DISABLE_NEW_PULL={{ gitea_mirror_disable_new_pull | bool | lower }}
|
||||||
|
GITEA__mirror__DISABLE_NEW_PUSH={{ gitea_mirror_disable_new_push | bool | lower }}
|
||||||
|
GITEA__mirror__DEFAULT_INTERVAL={{ gitea_mirror_default_interval }}
|
||||||
|
GITEA__mirror__MIN_INTERVAL={{ gitea_mirror_min_interval }}
|
||||||
|
|
||||||
|
{% if gitea_mirror_extra_config %}
|
||||||
|
# Additional Mirror Configuration
|
||||||
|
{% for item in gitea_mirror_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__mirror__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__mirror__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Metrics Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__metrics__ENABLED={{ gitea_metrics_enabled | bool | lower }}
|
||||||
|
{% if gitea_metrics_enabled and gitea_metrics_token %}
|
||||||
|
GITEA__metrics__TOKEN={{ gitea_metrics_token }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_metrics_extra_config %}
|
||||||
|
# Additional Metrics Configuration
|
||||||
|
{% for item in gitea_metrics_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__metrics__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__metrics__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# API Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__api__ENABLE_SWAGGER={{ gitea_api_enable_swagger | bool | lower }}
|
||||||
|
GITEA__api__MAX_RESPONSE_ITEMS={{ gitea_api_max_response_items }}
|
||||||
|
GITEA__api__DEFAULT_PAGING_NUM={{ gitea_api_default_paging_num }}
|
||||||
|
|
||||||
|
{% if gitea_api_extra_config %}
|
||||||
|
# Additional API Configuration
|
||||||
|
{% for item in gitea_api_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__api__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__api__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# OAuth2 Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__oauth2__ENABLED={{ gitea_oauth2_enabled | bool | lower }}
|
||||||
|
{% if gitea_oauth2_enabled %}
|
||||||
|
GITEA__oauth2__ACCESS_TOKEN_EXPIRATION_TIME={{ gitea_oauth2_access_token_expiration_time }}
|
||||||
|
GITEA__oauth2__REFRESH_TOKEN_EXPIRATION_TIME={{ gitea_oauth2_refresh_token_expiration_time }}
|
||||||
|
GITEA__oauth2__JWT_SIGNING_ALGORITHM={{ gitea_oauth2_jwt_signing_algorithm }}
|
||||||
|
{% if gitea_oauth2_jwt_secret %}
|
||||||
|
GITEA__oauth2__JWT_SECRET={{ gitea_oauth2_jwt_secret }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if gitea_oauth2_extra_config %}
|
||||||
|
# Additional OAuth2 Configuration
|
||||||
|
{% for item in gitea_oauth2_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__oauth2__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__oauth2__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Other Configuration
|
||||||
|
# ============================================
|
||||||
|
GITEA__other__SHOW_FOOTER_VERSION={{ gitea_show_footer_version | bool | lower }}
|
||||||
|
GITEA__other__SHOW_FOOTER_TEMPLATE_LOAD_TIME={{ gitea_show_footer_template_load_time | bool | lower }}
|
||||||
|
GITEA__other__ENABLE_SITEMAP={{ gitea_enable_sitemap | bool | lower }}
|
||||||
|
GITEA__other__ENABLE_FEED={{ gitea_enable_feed | bool | lower }}
|
||||||
|
|
||||||
|
{% if gitea_other_extra_config %}
|
||||||
|
# Additional Other Configuration
|
||||||
|
{% for item in gitea_other_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
GITEA__other__{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
GITEA__other__{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Additonal environment variables
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
{% for item in gitea_extra_config | dict2items %}
|
||||||
|
{% if item.value is boolean %}
|
||||||
|
{{ item.key }}={{ item.value | bool | lower }}
|
||||||
|
{% else %}
|
||||||
|
{{ item.key }}={{ item.value }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# gitea.local
|
||||||
|
[Definition]
|
||||||
|
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
|
||||||
|
ignoreregex =
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{# https://docs.gitea.com/administration/fail2ban-setup #}
|
||||||
|
|
||||||
|
[{{ gitea_fail2ban_jail_name }}]
|
||||||
|
enabled = true
|
||||||
|
filter = {{ gitea_fail2ban_filter }}
|
||||||
|
port = {{ gitea_fail2ban_port }}
|
||||||
|
logpath = {{ gitea_mounted_log_path }}
|
||||||
|
maxretry = {{ gitea_fail2ban_jail_maxretry }}
|
||||||
|
findtime = {{ gitea_fail2ban_jail_findtime }}
|
||||||
|
bantime = {{ gitea_fail2ban_jail_bantime }}
|
||||||
|
action = {{ gitea_fail2ban_jail_action }}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# Glance
|
||||||
|
|
||||||
|
Deploy Glance dashboard using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Glance is a self-hosted dashboard that displays information from various sources in a simple, configurable interface.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `glance_config_template` | `{{ app_templates_path }}/glance.yml.j2` | Template file for generating glance.yml config |
|
||||||
|
| `glance_config_path` | `{{ app_dir }}/config` | Configuration storage |
|
||||||
|
| `glance_http_port` | `8080` | Web interface port |
|
||||||
|
| `glance_container_version` | `latest` | Glance Docker image tag |
|
||||||
|
| `glance_restart_policy` | `{{ app_restart_policy }}` | Container restart policy |
|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.glance
|
||||||
|
vars:
|
||||||
|
glance_http_port: 3000
|
||||||
|
glance_config_template: "/path/to/your/custom/glance.yml.j2"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The role includes a default configuration template with example widgets (RSS feeds, weather, calendar, markets, etc.). To customize your dashboard:
|
||||||
|
|
||||||
|
1. **Option 1**: Create your own template file and set `glance_config_template` to point to it
|
||||||
|
2. **Option 2**: Manually edit `{app_dir}/glance.yml` after deployment
|
||||||
|
|
||||||
|
The default template includes widgets for:
|
||||||
|
- Calendar and weather
|
||||||
|
- RSS feeds (selfhosted, tech blogs)
|
||||||
|
- Twitch channels and YouTube videos
|
||||||
|
- Reddit subreddits and Hacker News
|
||||||
|
- Stock market data and GitHub releases
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
app_name: glance
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
glance_container_name: "{{ app_name | default('glance') }}"
|
||||||
|
glance_container_version: latest
|
||||||
|
glance_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
glance_http_port: 8080
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
glance_config_path: "{{ app_dir }}/config"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
glance_config_template: "{{ app_templates_path }}/glance.yml.j2"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Glance with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: glance
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ glance_config_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ glance_config_path }}"
|
||||||
|
app_extra_templates:
|
||||||
|
- src: "{{ glance_config_template }}"
|
||||||
|
dest: "{{ glance_config_path }}/glance.yml"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
glance:
|
||||||
|
container_name: {{ glance_container_name }}
|
||||||
|
image: glanceapp/glance:{{ glance_container_version }}
|
||||||
|
restart: {{ glance_restart_policy }}
|
||||||
|
volumes:
|
||||||
|
- {{ glance_config_path }}:/app/config
|
||||||
|
ports:
|
||||||
|
- "{{ glance_http_port }}:8080"
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
pages:
|
||||||
|
- name: Home
|
||||||
|
# Optionally, if you only have a single page you can hide the desktop navigation for a cleaner look
|
||||||
|
# hide-desktop-navigation: true
|
||||||
|
columns:
|
||||||
|
- size: small
|
||||||
|
widgets:
|
||||||
|
- type: calendar
|
||||||
|
first-day-of-week: monday
|
||||||
|
|
||||||
|
- type: rss
|
||||||
|
limit: 10
|
||||||
|
collapse-after: 3
|
||||||
|
cache: 12h
|
||||||
|
feeds:
|
||||||
|
- url: https://selfh.st/rss/
|
||||||
|
title: selfh.st
|
||||||
|
limit: 4
|
||||||
|
- url: https://ciechanow.ski/atom.xml
|
||||||
|
- url: https://www.joshwcomeau.com/rss.xml
|
||||||
|
title: Josh Comeau
|
||||||
|
- url: https://samwho.dev/rss.xml
|
||||||
|
- url: https://ishadeed.com/feed.xml
|
||||||
|
title: Ahmad Shadeed
|
||||||
|
|
||||||
|
- type: twitch-channels
|
||||||
|
channels:
|
||||||
|
- theprimeagen
|
||||||
|
- j_blow
|
||||||
|
- giantwaffle
|
||||||
|
- cohhcarnage
|
||||||
|
- christitustech
|
||||||
|
- EJ_SA
|
||||||
|
|
||||||
|
- size: full
|
||||||
|
widgets:
|
||||||
|
- type: group
|
||||||
|
widgets:
|
||||||
|
- type: hacker-news
|
||||||
|
- type: lobsters
|
||||||
|
|
||||||
|
- type: videos
|
||||||
|
channels:
|
||||||
|
- UCXuqSBlHAE6Xw-yeJA0Tunw # Linus Tech Tips
|
||||||
|
- UCR-DXc1voovS8nhAvccRZhg # Jeff Geerling
|
||||||
|
- UCsBjURrPoezykLs9EqgamOA # Fireship
|
||||||
|
- UCBJycsmduvYEL83R_U4JriQ # Marques Brownlee
|
||||||
|
- UCHnyfMqiRRG1u-2MsSQLbXA # Veritasium
|
||||||
|
|
||||||
|
- type: group
|
||||||
|
widgets:
|
||||||
|
- type: reddit
|
||||||
|
subreddit: technology
|
||||||
|
show-thumbnails: true
|
||||||
|
- type: reddit
|
||||||
|
subreddit: selfhosted
|
||||||
|
show-thumbnails: true
|
||||||
|
|
||||||
|
- size: small
|
||||||
|
widgets:
|
||||||
|
- type: weather
|
||||||
|
location: London, United Kingdom
|
||||||
|
units: metric # alternatively "imperial"
|
||||||
|
hour-format: 12h # alternatively "24h"
|
||||||
|
# Optionally hide the location from being displayed in the widget
|
||||||
|
# hide-location: true
|
||||||
|
|
||||||
|
- type: markets
|
||||||
|
markets:
|
||||||
|
- symbol: SPY
|
||||||
|
name: S&P 500
|
||||||
|
- symbol: BTC-USD
|
||||||
|
name: Bitcoin
|
||||||
|
- symbol: NVDA
|
||||||
|
name: NVIDIA
|
||||||
|
- symbol: AAPL
|
||||||
|
name: Apple
|
||||||
|
- symbol: MSFT
|
||||||
|
name: Microsoft
|
||||||
|
|
||||||
|
- type: releases
|
||||||
|
cache: 1d
|
||||||
|
# Without authentication the Github API allows for up to 60 requests per hour. You can create a
|
||||||
|
# read-only token from your Github account settings and use it here to increase the limit.
|
||||||
|
# token: ...
|
||||||
|
repositories:
|
||||||
|
- glanceapp/glance
|
||||||
|
- go-gitea/gitea
|
||||||
|
- immich-app/immich
|
||||||
|
- syncthing/syncthing
|
||||||
|
|
||||||
|
# Add more pages here:
|
||||||
|
# - name: Your page name
|
||||||
|
# columns:
|
||||||
|
# - size: small
|
||||||
|
# widgets:
|
||||||
|
# # Add widgets here
|
||||||
|
|
||||||
|
# - size: full
|
||||||
|
# widgets:
|
||||||
|
# # Add widgets here
|
||||||
|
|
||||||
|
# - size: small
|
||||||
|
# widgets:
|
||||||
|
# # Add widgets here
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Grafana
|
||||||
|
|
||||||
|
Deploy Grafana data visualization platform using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Grafana is an analytics and monitoring platform with beautiful dashboards and alerting capabilities.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `grafana_http_port` | `3000` | Web interface port |
|
||||||
|
| `grafana_data_path` | `{{ app_dir }}/data` | Data storage |
|
||||||
|
| `grafana_container_version` | `latest` | Grafana Docker image tag |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.grafana
|
||||||
|
vars:
|
||||||
|
grafana_http_port: 3001
|
||||||
|
```
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
app_name: grafana
|
||||||
|
|
||||||
|
grafana_container_name: "{{ app_name | default('grafana') }}"
|
||||||
|
grafana_container_version: latest
|
||||||
|
grafana_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
grafana_http_port: 3000
|
||||||
|
grafana_data_path: "{{ app_dir }}/data"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy grafana with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: grafana
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ grafana_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ grafana_data_path }}"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
grafana:
|
||||||
|
image: "grafana/grafana-oss:{{ grafana_container_version }}"
|
||||||
|
container_name: "{{ grafana_container_name }}"
|
||||||
|
restart: "{{ grafana_restart_policy }}"
|
||||||
|
ports:
|
||||||
|
- "{{ grafana_http_port }}:3000"
|
||||||
|
volumes:
|
||||||
|
- "{{ grafana_data_path }}:/var/lib/grafana"
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# Immich
|
||||||
|
|
||||||
|
Deploy Immich photo management platform using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Immich is a self-hosted photo and video backup solution with mobile apps, AI features, and automatic organization. Includes web server, machine learning, PostgreSQL database, and Redis.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required (Set in Vault)
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `immich_db_password` | PostgreSQL database password (use only A-Za-z0-9 characters) |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `immich_http_port` | `2283` | Web interface port |
|
||||||
|
| `immich_library_path` | `{{ app_dir }}/library` | Photo and video upload storage location |
|
||||||
|
| `immich_pgdata_path` | `{{ app_dir }}/pgdata` | PostgreSQL database storage location |
|
||||||
|
| `immich_container_version` | `v2` | Immich version tag (can pin to specific version like "v2.1.0") |
|
||||||
|
| `immich_container_name` | `{{ app_name }}` | Container name |
|
||||||
|
| `immich_restart_policy` | `{{ app_restart_policy }}` | Container restart policy |
|
||||||
|
| `immich_timezone` | `{{ app_timezone }}` | Container timezone |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.immich
|
||||||
|
vars:
|
||||||
|
immich_db_password: "{{ vault_immich_db_password }}"
|
||||||
|
immich_library_path: /storage/photos
|
||||||
|
immich_container_version: "v2.1.0"
|
||||||
|
```
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
app_name: immich
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
immich_container_name: "{{ app_name | default('immich') }}"
|
||||||
|
immich_container_version: v2
|
||||||
|
immich_restart_policy: "{{ app_restart_policy | default('unless-stopped') }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
immich_http_port: 2283
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
immich_library_path: "{{ app_dir }}/library"
|
||||||
|
immich_pgdata_path: "{{ app_dir }}/pgdata"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
immich_db_password: postgres
|
||||||
|
immich_timezone: "{{ app_timezone }}"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description:: Deploy Immich with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: immich
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ immich_library_path }}"
|
||||||
|
- "{{ immich_pgdata_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ immich_library_path }}"
|
||||||
|
- "{{ immich_pgdata_path }}"
|
||||||
|
app_extra_templates:
|
||||||
|
- src: "{{ app_templates_path }}/.env.j2"
|
||||||
|
dest: "{{ app_dir }}/.env"
|
||||||
|
app_compose_validate: false
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables
|
||||||
|
|
||||||
|
# The location where your uploaded files are stored
|
||||||
|
UPLOAD_LOCATION={{ immich_library_path }}
|
||||||
|
|
||||||
|
# The location where your database files are stored. Network shares are not supported for the database
|
||||||
|
DB_DATA_LOCATION={{ immich_pgdata_path }}
|
||||||
|
|
||||||
|
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
|
||||||
|
TZ={{ immich_timezone }}
|
||||||
|
|
||||||
|
# The Immich version to use. You can pin this to a specific version like "v2.1.0"
|
||||||
|
IMMICH_VERSION={{ immich_container_version }}
|
||||||
|
|
||||||
|
# Connection secret for postgres. You should change it to a random password
|
||||||
|
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
|
||||||
|
DB_PASSWORD={{ immich_db_password }}
|
||||||
|
|
||||||
|
# The values below this line do not need to be changed
|
||||||
|
###################################################################################
|
||||||
|
DB_USERNAME=postgres
|
||||||
|
DB_DATABASE_NAME=immich
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
name: immich
|
||||||
|
|
||||||
|
services:
|
||||||
|
immich-server:
|
||||||
|
container_name: "{{ immich_container_name }}"
|
||||||
|
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
|
||||||
|
# extends:
|
||||||
|
# file: hwaccel.transcoding.yml
|
||||||
|
# service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
|
||||||
|
volumes:
|
||||||
|
# Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
|
||||||
|
- ${UPLOAD_LOCATION}:/data
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "{{ immich_http_port }}:2283"
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
- database
|
||||||
|
restart: {{ immich_restart_policy }}
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
|
immich-machine-learning:
|
||||||
|
container_name: immich_machine_learning
|
||||||
|
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
|
||||||
|
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
||||||
|
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||||
|
# extends: # uncomment this section for hardware acceleration - see https://docs.immich.app/features/ml-hardware-acceleration
|
||||||
|
# file: hwaccel.ml.yml
|
||||||
|
# service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
||||||
|
volumes:
|
||||||
|
- model-cache:/cache
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: {{ immich_restart_policy }}
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
|
redis:
|
||||||
|
container_name: immich_redis
|
||||||
|
image: docker.io/valkey/valkey:9@sha256:fb8d272e529ea567b9bf1302245796f21a2672b8368ca3fcb938ac334e613c8f
|
||||||
|
healthcheck:
|
||||||
|
test: redis-cli ping || exit 1
|
||||||
|
restart: {{ immich_restart_policy }}
|
||||||
|
|
||||||
|
database:
|
||||||
|
container_name: immich_postgres
|
||||||
|
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:bcf63357191b76a916ae5eb93464d65c07511da41e3bf7a8416db519b40b1c23
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
|
POSTGRES_INITDB_ARGS: '--data-checksums'
|
||||||
|
# Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
|
||||||
|
# DB_STORAGE_TYPE: 'HDD'
|
||||||
|
volumes:
|
||||||
|
# Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
|
||||||
|
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||||
|
shm_size: 128mb
|
||||||
|
restart: {{ immich_restart_policy }}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
model-cache:
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# InfluxDB
|
||||||
|
|
||||||
|
Deploy InfluxDB time series database using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
InfluxDB is a high-performance time series database designed for handling large amounts of timestamped data. This deploys InfluxDB v2 with web UI and API.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `influxdb_http_port` | `8086` | HTTP API and web UI port |
|
||||||
|
| `influxdb_udp_port` | `8089` | UDP port for data ingestion |
|
||||||
|
| `influxdb_data_path` | `{{ app_dir }}/data` | Database storage location |
|
||||||
|
| `influxdb_config_path` | `{{ app_dir }}/config` | Configuration files location |
|
||||||
|
| `influxdb_container_version` | `latest` | InfluxDB Docker image tag |
|
||||||
|
| `influxdb_container_name` | `{{ app_name }}` | Container name |
|
||||||
|
| `influxdb_restart_policy` | `{{ app_restart_policy }}` | Container restart policy |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.influxdb
|
||||||
|
vars:
|
||||||
|
influxdb_http_port: 8087
|
||||||
|
influxdb_container_version: "2.7"
|
||||||
|
```
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
app_name: influxdb
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
influxdb_container_name: "{{ app_name | default('influxdb') }}"
|
||||||
|
influxdb_container_version: latest
|
||||||
|
influxdb_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
influxdb_http_port: 8086
|
||||||
|
influxdb_udp_port: 8089
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
influxdb_data_path: "{{ app_dir }}/data"
|
||||||
|
influxdb_config_path: "{{ app_dir }}/config"
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: <your_name>
|
||||||
|
description: Deploy influxdb with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: influxdb
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ influxdb_data_path }}"
|
||||||
|
- "{{ influxdb_config_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ influxdb_data_path }}"
|
||||||
|
- "{{ influxdb_config_path }}"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
influxdb:
|
||||||
|
image: "influxdb:{{ influxdb_container_version }}"
|
||||||
|
container_name: "{{ influxdb_container_name }}"
|
||||||
|
restart: "{{ influxdb_restart_policy }}"
|
||||||
|
ports:
|
||||||
|
- "{{ influxdb_http_port }}:8086"
|
||||||
|
- "{{ influxdb_udp_port }}:8089/udp"
|
||||||
|
volumes:
|
||||||
|
- "{{ influxdb_data_path }}:/var/lib/influxdb2"
|
||||||
|
- "{{ influxdb_config_path }}:/etc/influxdb2"
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Jellyfin
|
||||||
|
|
||||||
|
Deploy Jellyfin media server using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Jellyfin is a free and open-source media server for organizing, managing, and streaming media files with optional GPU hardware acceleration.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `jellyfin_http_port` | `8096` | Web interface port |
|
||||||
|
| `jellyfin_discovery_port` | `7359` | Auto-discovery port |
|
||||||
|
| `jellyfin_config_path` | `{{ app_dir }}/config` | Configuration storage |
|
||||||
|
| `jellyfin_cache_path` | `{{ app_dir }}/cache` | Cache storage |
|
||||||
|
| `jellyfin_container_version` | `latest` | Jellyfin Docker image tag |
|
||||||
|
| `jellyfin_container_name` | `{{ app_name }}` | Container name |
|
||||||
|
| `jellyfin_restart_policy` | `{{ app_restart_policy }}` | Container restart policy |
|
||||||
|
| `jellyfin_uid` | `{{ app_uid }}` | User ID for file permissions |
|
||||||
|
| `jellyfin_gid` | `{{ app_gid }}` | Group ID for file permissions |
|
||||||
|
| `jellyfin_gpu_passthrough` | `false` | Enable NVIDIA GPU support |
|
||||||
|
| `jellyfin_server_url` | See defaults | Custom domain for server |
|
||||||
|
| `jellyfin_libraries` | `[]` | List of media library mappings with `host_path` and `container_path` |
|
||||||
|
|
||||||
|
#### Example Media Libraries Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jellyfin_libraries:
|
||||||
|
- host_path: "/storage/movies"
|
||||||
|
container_path: /movies
|
||||||
|
- host_path: "/storage/tv_shows"
|
||||||
|
container_path: /tv_shows
|
||||||
|
- host_path: "/storage/anime"
|
||||||
|
container_path: /anime
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.jellyfin
|
||||||
|
vars:
|
||||||
|
shared_media_path: /storage/media
|
||||||
|
jellyfin_gpu_passthrough: true
|
||||||
|
jellyfin_libraries:
|
||||||
|
- host_path: /storage/media/movies
|
||||||
|
container_path: /movies
|
||||||
|
```
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
app_name: jellyfin
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
jellyfin_container_name: "{{ app_name | default('jellyfin') }}"
|
||||||
|
jellyfin_container_version: latest
|
||||||
|
jellyfin_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
jellyfin_uid: "{{ app_uid }}"
|
||||||
|
jellyfin_gid: "{{ app_gid }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
jellyfin_http_port: 8096
|
||||||
|
jellyfin_discovery_port: 7359
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
jellyfin_config_path: "{{ app_dir }}/config"
|
||||||
|
jellyfin_cache_path: "{{ app_dir }}/cache"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
jellyfin_gpu_passthrough: false
|
||||||
|
jellyfin_libraries: []
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Jellyfin with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: jellyfin
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ jellyfin_config_path }}"
|
||||||
|
- "{{ jellyfin_cache_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ jellyfin_config_path }}"
|
||||||
|
- "{{ jellyfin_cache_path }}"
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
jellyfin:
|
||||||
|
image: "jellyfin/jellyfin:{{ jellyfin_container_version }}"
|
||||||
|
container_name: "{{ jellyfin_container_name }}"
|
||||||
|
user: {{ jellyfin_uid }}:{{ jellyfin_gid }}
|
||||||
|
restart: {{ jellyfin_restart_policy }}
|
||||||
|
ports:
|
||||||
|
- {{ jellyfin_http_port }}:8096/tcp
|
||||||
|
- {{ jellyfin_discovery_port }}:7359/udp
|
||||||
|
volumes:
|
||||||
|
- "{{ jellyfin_config_path }}:/config"
|
||||||
|
- "{{ jellyfin_cache_path }}:/cache"
|
||||||
|
{% for item in jellyfin_libraries %}
|
||||||
|
- "{{ item.host_path }}:{{ item.container_path }}:ro"
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if jellyfin_server_url %}
|
||||||
|
# Optional - alternative address used for autodiscovery
|
||||||
|
environment:
|
||||||
|
- JELLYFIN_PublishedServerUrl={{ jellyfin_server_url }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if jellyfin_gpu_passthrough %}
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: 1
|
||||||
|
capabilities: [gpu]
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Linkwarden
|
||||||
|
|
||||||
|
Deploy Linkwarden bookmark manager using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Linkwarden is a self-hosted bookmark manager with tagging, collections, and full-text search capabilities.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required (Set in Vault)
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `linkwarden_nextauth_secret` | NextAuth authentication secret |
|
||||||
|
| `linkwarden_postgres_password` | PostgreSQL database password |
|
||||||
|
| `linkwarden_meili_master_key` | Meilisearch master key for search functionality |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `linkwarden_http_port` | `3000` | Web interface port |
|
||||||
|
| `linkwarden_data_path` | `{{ app_dir }}/data` | Application data storage path |
|
||||||
|
| `linkwarden_pgdata_path` | `{{ app_dir }}/pgdata` | PostgreSQL data storage path |
|
||||||
|
| `linkwarden_meili_data_path` | `{{ app_dir }}/meili_data` | Meilisearch data storage path |
|
||||||
|
| `linkwarden_container_version` | `latest` | Linkwarden Docker image tag |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.linkwarden
|
||||||
|
vars:
|
||||||
|
linkwarden_http_port: 3001
|
||||||
|
```
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
app_name: linkwarden
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
linkwarden_container_name: "{{ app_name | default('linkwarden') }}"
|
||||||
|
linkwarden_container_version: latest
|
||||||
|
linkwarden_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
linkwarden_http_port: 3000
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
linkwarden_data_path: "{{ app_dir }}/data"
|
||||||
|
linkwarden_pgdata_path: "{{ app_dir }}/pgdata"
|
||||||
|
linkwarden_meili_data_path: "{{ app_dir }}/meili_data"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
linkwarden_nextauth_secret: change-me!
|
||||||
|
linkwarden_postgres_password: change-me!
|
||||||
|
linkwarden_meili_master_key: change-me!
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Linkwarden with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: linkwarden
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ linkwarden_data_path }}"
|
||||||
|
- "{{ linkwarden_pgdata_path }}"
|
||||||
|
- "{{ linkwarden_meili_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ linkwarden_data_path }}"
|
||||||
|
- "{{ linkwarden_pgdata_path }}"
|
||||||
|
- "{{ linkwarden_meili_data_path }}"
|
||||||
|
app_extra_templates:
|
||||||
|
- src: "{{ app_templates_path }}/.env.j2"
|
||||||
|
dest: "{{ app_dir }}/.env"
|
||||||
|
app_compose_validate: false # Issues validating when needing a .env
|
||||||
@@ -0,0 +1,473 @@
|
|||||||
|
NEXTAUTH_URL=http://localhost:3000/api/v1/auth
|
||||||
|
NEXTAUTH_SECRET={{ linkwarden_nextauth_secret }}
|
||||||
|
|
||||||
|
# Manual installation database settings
|
||||||
|
# Example: DATABASE_URL=postgresql://user:password@localhost:5432/linkwarden
|
||||||
|
DATABASE_URL=
|
||||||
|
|
||||||
|
# Docker installation database settings
|
||||||
|
POSTGRES_PASSWORD={{ linkwarden_postgres_password }}
|
||||||
|
|
||||||
|
# Additional Optional Settings
|
||||||
|
PAGINATION_TAKE_COUNT=
|
||||||
|
STORAGE_FOLDER=
|
||||||
|
AUTOSCROLL_TIMEOUT=
|
||||||
|
NEXT_PUBLIC_DISABLE_REGISTRATION=
|
||||||
|
NEXT_PUBLIC_CREDENTIALS_ENABLED=
|
||||||
|
DISABLE_NEW_SSO_USERS=
|
||||||
|
MAX_LINKS_PER_USER=
|
||||||
|
ARCHIVE_TAKE_COUNT=
|
||||||
|
BROWSER_TIMEOUT=
|
||||||
|
IGNORE_UNAUTHORIZED_CA=
|
||||||
|
IGNORE_HTTPS_ERRORS=
|
||||||
|
IGNORE_URL_SIZE_LIMIT=
|
||||||
|
NEXT_PUBLIC_DEMO=
|
||||||
|
NEXT_PUBLIC_DEMO_USERNAME=
|
||||||
|
NEXT_PUBLIC_DEMO_PASSWORD=
|
||||||
|
NEXT_PUBLIC_ADMIN=
|
||||||
|
NEXT_PUBLIC_MAX_FILE_BUFFER=
|
||||||
|
PDF_MAX_BUFFER=
|
||||||
|
SCREENSHOT_MAX_BUFFER=
|
||||||
|
READABILITY_MAX_BUFFER=
|
||||||
|
PREVIEW_MAX_BUFFER=
|
||||||
|
MONOLITH_MAX_BUFFER=
|
||||||
|
MONOLITH_CUSTOM_OPTIONS=
|
||||||
|
IMPORT_LIMIT=
|
||||||
|
PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH=
|
||||||
|
PLAYWRIGHT_WS_URL=
|
||||||
|
MAX_WORKERS=
|
||||||
|
DISABLE_PRESERVATION=
|
||||||
|
NEXT_PUBLIC_RSS_POLLING_INTERVAL_MINUTES=
|
||||||
|
RSS_SUBSCRIPTION_LIMIT_PER_USER=
|
||||||
|
TEXT_CONTENT_LIMIT=
|
||||||
|
SEARCH_FILTER_LIMIT=
|
||||||
|
INDEX_TAKE_COUNT=
|
||||||
|
MEILI_TIMEOUT=
|
||||||
|
|
||||||
|
# AI Settings
|
||||||
|
NEXT_PUBLIC_OLLAMA_ENDPOINT_URL=
|
||||||
|
OLLAMA_MODEL=
|
||||||
|
|
||||||
|
# https://ai-sdk.dev/providers/openai-compatible-providers
|
||||||
|
OPENAI_API_KEY=
|
||||||
|
OPENAI_MODEL=
|
||||||
|
# Optional: Set a custom OpenAI base URL and name (for third-party providers)
|
||||||
|
CUSTOM_OPENAI_BASE_URL=
|
||||||
|
CUSTOM_OPENAI_NAME=
|
||||||
|
|
||||||
|
# https://sdk.vercel.ai/providers/ai-sdk-providers/azure
|
||||||
|
AZURE_API_KEY=
|
||||||
|
AZURE_RESOURCE_NAME=
|
||||||
|
AZURE_MODEL=
|
||||||
|
|
||||||
|
# https://sdk.vercel.ai/providers/ai-sdk-providers/anthropic
|
||||||
|
ANTHROPIC_API_KEY=
|
||||||
|
ANTHROPIC_MODEL=
|
||||||
|
|
||||||
|
# https://github.com/OpenRouterTeam/ai-sdk-provider
|
||||||
|
OPENROUTER_API_KEY=
|
||||||
|
OPENROUTER_MODEL=
|
||||||
|
|
||||||
|
# https://ai-sdk.dev/providers/ai-sdk-providers/perplexity
|
||||||
|
PERPLEXITY_API_KEY=
|
||||||
|
PERPLEXITY_MODEL=
|
||||||
|
|
||||||
|
# MeiliSearch Settings
|
||||||
|
MEILI_HOST=
|
||||||
|
MEILI_MASTER_KEY={{ linkwarden_meili_master_key }}
|
||||||
|
|
||||||
|
# AWS S3 Settings
|
||||||
|
SPACES_KEY=
|
||||||
|
SPACES_SECRET=
|
||||||
|
SPACES_ENDPOINT=
|
||||||
|
SPACES_BUCKET_NAME=
|
||||||
|
SPACES_REGION=
|
||||||
|
SPACES_FORCE_PATH_STYLE=
|
||||||
|
|
||||||
|
# SMTP Settings
|
||||||
|
NEXT_PUBLIC_EMAIL_PROVIDER=
|
||||||
|
EMAIL_FROM=
|
||||||
|
EMAIL_SERVER=
|
||||||
|
BASE_URL=
|
||||||
|
|
||||||
|
# Proxy settings
|
||||||
|
PROXY=
|
||||||
|
PROXY_USERNAME=
|
||||||
|
PROXY_PASSWORD=
|
||||||
|
PROXY_BYPASS=
|
||||||
|
|
||||||
|
# PDF archive settings
|
||||||
|
PDF_MARGIN_TOP=
|
||||||
|
PDF_MARGIN_BOTTOM=
|
||||||
|
|
||||||
|
#################
|
||||||
|
# SSO Providers #
|
||||||
|
#################
|
||||||
|
|
||||||
|
# 42 School
|
||||||
|
NEXT_PUBLIC_FORTYTWO_ENABLED=
|
||||||
|
FORTYTWO_CUSTOM_NAME=
|
||||||
|
FORTYTWO_CLIENT_ID=
|
||||||
|
FORTYTWO_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Apple
|
||||||
|
NEXT_PUBLIC_APPLE_ENABLED=
|
||||||
|
APPLE_CUSTOM_NAME=
|
||||||
|
APPLE_ID=
|
||||||
|
APPLE_SECRET=
|
||||||
|
|
||||||
|
# Atlassian
|
||||||
|
NEXT_PUBLIC_ATLASSIAN_ENABLED=
|
||||||
|
ATLASSIAN_CUSTOM_NAME=
|
||||||
|
ATLASSIAN_CLIENT_ID=
|
||||||
|
ATLASSIAN_CLIENT_SECRET=
|
||||||
|
ATLASSIAN_SCOPE=
|
||||||
|
|
||||||
|
# Auth0
|
||||||
|
NEXT_PUBLIC_AUTH0_ENABLED=
|
||||||
|
AUTH0_CUSTOM_NAME=
|
||||||
|
AUTH0_ISSUER=
|
||||||
|
AUTH0_CLIENT_SECRET=
|
||||||
|
AUTH0_CLIENT_ID=
|
||||||
|
|
||||||
|
# Authelia
|
||||||
|
NEXT_PUBLIC_AUTHELIA_ENABLED=
|
||||||
|
AUTHELIA_CLIENT_ID=
|
||||||
|
AUTHELIA_CLIENT_SECRET=
|
||||||
|
AUTHELIA_WELLKNOWN_URL=
|
||||||
|
|
||||||
|
# Authentik
|
||||||
|
NEXT_PUBLIC_AUTHENTIK_ENABLED=
|
||||||
|
AUTHENTIK_CUSTOM_NAME=
|
||||||
|
AUTHENTIK_ISSUER=
|
||||||
|
AUTHENTIK_CLIENT_ID=
|
||||||
|
AUTHENTIK_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Azure AD B2C
|
||||||
|
NEXT_PUBLIC_AZURE_AD_B2C_ENABLED=
|
||||||
|
AZURE_AD_B2C_TENANT_NAME=
|
||||||
|
AZURE_AD_B2C_CLIENT_ID=
|
||||||
|
AZURE_AD_B2C_CLIENT_SECRET=
|
||||||
|
AZURE_AD_B2C_PRIMARY_USER_FLOW=
|
||||||
|
|
||||||
|
# Azure AD
|
||||||
|
NEXT_PUBLIC_AZURE_AD_ENABLED=
|
||||||
|
AZURE_AD_CLIENT_ID=
|
||||||
|
AZURE_AD_CLIENT_SECRET=
|
||||||
|
AZURE_AD_TENANT_ID=
|
||||||
|
|
||||||
|
# Battle.net
|
||||||
|
NEXT_PUBLIC_BATTLENET_ENABLED=
|
||||||
|
BATTLENET_CUSTOM_NAME=
|
||||||
|
BATTLENET_CLIENT_ID=
|
||||||
|
BATTLENET_CLIENT_SECRET=
|
||||||
|
BATTLENET_ISSUER=
|
||||||
|
|
||||||
|
# Box
|
||||||
|
NEXT_PUBLIC_BOX_ENABLED=
|
||||||
|
BOX_CUSTOM_NAME=
|
||||||
|
BOX_CLIENT_ID=
|
||||||
|
BOX_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Bungie
|
||||||
|
NEXT_PUBLIC_BUNGIE_ENABLED=
|
||||||
|
BUNGIE_CUSTOM_NAME=
|
||||||
|
BUNGIE_CLIENT_ID=
|
||||||
|
BUNGIE_CLIENT_SECRET=
|
||||||
|
BUNGIE_API_KEY=
|
||||||
|
|
||||||
|
# Cognito
|
||||||
|
NEXT_PUBLIC_COGNITO_ENABLED=
|
||||||
|
COGNITO_CUSTOM_NAME=
|
||||||
|
COGNITO_CLIENT_ID=
|
||||||
|
COGNITO_CLIENT_SECRET=
|
||||||
|
COGNITO_ISSUER=
|
||||||
|
|
||||||
|
# Coinbase
|
||||||
|
NEXT_PUBLIC_COINBASE_ENABLED=
|
||||||
|
COINBASE_CUSTOM_NAME=
|
||||||
|
COINBASE_CLIENT_ID=
|
||||||
|
COINBASE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Discord
|
||||||
|
NEXT_PUBLIC_DISCORD_ENABLED=
|
||||||
|
DISCORD_CUSTOM_NAME=
|
||||||
|
DISCORD_CLIENT_ID=
|
||||||
|
DISCORD_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Dropbox
|
||||||
|
NEXT_PUBLIC_DROPBOX_ENABLED=
|
||||||
|
DROPBOX_CUSTOM_NAME=
|
||||||
|
DROPBOX_CLIENT_ID=
|
||||||
|
DROPBOX_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# DuendeIndentityServer6
|
||||||
|
NEXT_PUBLIC_DUENDE_IDS6_ENABLED=
|
||||||
|
DUENDE_IDS6_CUSTOM_NAME=
|
||||||
|
DUENDE_IDS6_CLIENT_ID=
|
||||||
|
DUENDE_IDS6_CLIENT_SECRET=
|
||||||
|
DUENDE_IDS6_ISSUER=
|
||||||
|
|
||||||
|
# EVE Online
|
||||||
|
NEXT_PUBLIC_EVEONLINE_ENABLED=
|
||||||
|
EVEONLINE_CUSTOM_NAME=
|
||||||
|
EVEONLINE_CLIENT_ID=
|
||||||
|
EVEONLINE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Facebook
|
||||||
|
NEXT_PUBLIC_FACEBOOK_ENABLED=
|
||||||
|
FACEBOOK_CUSTOM_NAME=
|
||||||
|
FACEBOOK_CLIENT_ID=
|
||||||
|
FACEBOOK_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# FACEIT
|
||||||
|
NEXT_PUBLIC_FACEIT_ENABLED=
|
||||||
|
FACEIT_CUSTOM_NAME=
|
||||||
|
FACEIT_CLIENT_ID=
|
||||||
|
FACEIT_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Foursquare
|
||||||
|
NEXT_PUBLIC_FOURSQUARE_ENABLED=
|
||||||
|
FOURSQUARE_CUSTOM_NAME=
|
||||||
|
FOURSQUARE_CLIENT_ID=
|
||||||
|
FOURSQUARE_CLIENT_SECRET=
|
||||||
|
FOURSQUARE_APIVERSION=
|
||||||
|
|
||||||
|
# Freshbooks
|
||||||
|
NEXT_PUBLIC_FRESHBOOKS_ENABLED=
|
||||||
|
FRESHBOOKS_CUSTOM_NAME=
|
||||||
|
FRESHBOOKS_CLIENT_ID=
|
||||||
|
FRESHBOOKS_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# FusionAuth
|
||||||
|
NEXT_PUBLIC_FUSIONAUTH_ENABLED=
|
||||||
|
FUSIONAUTH_CUSTOM_NAME=
|
||||||
|
FUSIONAUTH_CLIENT_ID=
|
||||||
|
FUSIONAUTH_CLIENT_SECRET=
|
||||||
|
FUSIONAUTH_ISSUER=
|
||||||
|
FUSIONAUTH_TENANT_ID=
|
||||||
|
|
||||||
|
# GitHub
|
||||||
|
NEXT_PUBLIC_GITHUB_ENABLED=
|
||||||
|
GITHUB_CUSTOM_NAME=
|
||||||
|
GITHUB_ID=
|
||||||
|
GITHUB_SECRET=
|
||||||
|
|
||||||
|
# GitLab
|
||||||
|
NEXT_PUBLIC_GITLAB_ENABLED=
|
||||||
|
GITLAB_CUSTOM_NAME=
|
||||||
|
GITLAB_CLIENT_ID=
|
||||||
|
GITLAB_CLIENT_SECRET=
|
||||||
|
GITLAB_AUTH_URL=
|
||||||
|
|
||||||
|
# Google
|
||||||
|
NEXT_PUBLIC_GOOGLE_ENABLED=
|
||||||
|
GOOGLE_CUSTOM_NAME=
|
||||||
|
GOOGLE_CLIENT_ID=
|
||||||
|
GOOGLE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# HubSpot
|
||||||
|
NEXT_PUBLIC_HUBSPOT_ENABLED=
|
||||||
|
HUBSPOT_CUSTOM_NAME=
|
||||||
|
HUBSPOT_CLIENT_ID=
|
||||||
|
HUBSPOT_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# IdentityServer4
|
||||||
|
NEXT_PUBLIC_IDS4_ENABLED=
|
||||||
|
IDS4_CUSTOM_NAME=
|
||||||
|
IDS4_CLIENT_ID=
|
||||||
|
IDS4_CLIENT_SECRET=
|
||||||
|
IDS4_ISSUER=
|
||||||
|
|
||||||
|
# Kakao
|
||||||
|
NEXT_PUBLIC_KAKAO_ENABLED=
|
||||||
|
KAKAO_CUSTOM_NAME=
|
||||||
|
KAKAO_CLIENT_ID=
|
||||||
|
KAKAO_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Keycloak
|
||||||
|
NEXT_PUBLIC_KEYCLOAK_ENABLED=
|
||||||
|
KEYCLOAK_CUSTOM_NAME=
|
||||||
|
KEYCLOAK_ISSUER=
|
||||||
|
KEYCLOAK_CLIENT_ID=
|
||||||
|
KEYCLOAK_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# LINE
|
||||||
|
NEXT_PUBLIC_LINE_ENABLED=
|
||||||
|
LINE_CUSTOM_NAME=
|
||||||
|
LINE_CLIENT_ID=
|
||||||
|
LINE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# LinkedIn
|
||||||
|
NEXT_PUBLIC_LINKEDIN_ENABLED=
|
||||||
|
LINKEDIN_CUSTOM_NAME=
|
||||||
|
LINKEDIN_CLIENT_ID=
|
||||||
|
LINKEDIN_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Mailchimp
|
||||||
|
NEXT_PUBLIC_MAILCHIMP_ENABLED=
|
||||||
|
MAILCHIMP_CUSTOM_NAME=
|
||||||
|
MAILCHIMP_CLIENT_ID=
|
||||||
|
MAILCHIMP_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Mail.ru
|
||||||
|
NEXT_PUBLIC_MAILRU_ENABLED=
|
||||||
|
MAILRU_CUSTOM_NAME=
|
||||||
|
MAILRU_CLIENT_ID=
|
||||||
|
MAILRU_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Naver
|
||||||
|
NEXT_PUBLIC_NAVER_ENABLED=
|
||||||
|
NAVER_CUSTOM_NAME=
|
||||||
|
NAVER_CLIENT_ID=
|
||||||
|
NAVER_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Netlify
|
||||||
|
NEXT_PUBLIC_NETLIFY_ENABLED=
|
||||||
|
NETLIFY_CUSTOM_NAME=
|
||||||
|
NETLIFY_CLIENT_ID=
|
||||||
|
NETLIFY_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Okta
|
||||||
|
NEXT_PUBLIC_OKTA_ENABLED=
|
||||||
|
OKTA_CUSTOM_NAME=
|
||||||
|
OKTA_CLIENT_ID=
|
||||||
|
OKTA_CLIENT_SECRET=
|
||||||
|
OKTA_ISSUER=
|
||||||
|
|
||||||
|
# OneLogin
|
||||||
|
NEXT_PUBLIC_ONELOGIN_ENABLED=
|
||||||
|
ONELOGIN_CUSTOM_NAME=
|
||||||
|
ONELOGIN_CLIENT_ID=
|
||||||
|
ONELOGIN_CLIENT_SECRET=
|
||||||
|
ONELOGIN_ISSUER=
|
||||||
|
|
||||||
|
# Osso
|
||||||
|
NEXT_PUBLIC_OSSO_ENABLED=
|
||||||
|
OSSO_CUSTOM_NAME=
|
||||||
|
OSSO_CLIENT_ID=
|
||||||
|
OSSO_CLIENT_SECRET=
|
||||||
|
OSSO_ISSUER=
|
||||||
|
|
||||||
|
# osu!
|
||||||
|
NEXT_PUBLIC_OSU_ENABLED=
|
||||||
|
OSU_CUSTOM_NAME=
|
||||||
|
OSU_CLIENT_ID=
|
||||||
|
OSU_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Patreon
|
||||||
|
NEXT_PUBLIC_PATREON_ENABLED=
|
||||||
|
PATREON_CUSTOM_NAME=
|
||||||
|
PATREON_CLIENT_ID=
|
||||||
|
PATREON_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Pinterest
|
||||||
|
NEXT_PUBLIC_PINTEREST_ENABLED=
|
||||||
|
PINTEREST_CUSTOM_NAME=
|
||||||
|
PINTEREST_CLIENT_ID=
|
||||||
|
PINTEREST_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Pipedrive
|
||||||
|
NEXT_PUBLIC_PIPEDRIVE_ENABLED=
|
||||||
|
PIPEDRIVE_CUSTOM_NAME=
|
||||||
|
PIPEDRIVE_CLIENT_ID=
|
||||||
|
PIPEDRIVE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Reddit
|
||||||
|
NEXT_PUBLIC_REDDIT_ENABLED=
|
||||||
|
REDDIT_CUSTOM_NAME=
|
||||||
|
REDDIT_CLIENT_ID=
|
||||||
|
REDDIT_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Salesforce
|
||||||
|
NEXT_PUBLIC_SALESFORCE_ENABLED=
|
||||||
|
SALESFORCE_CUSTOM_NAME=
|
||||||
|
SALESFORCE_CLIENT_ID=
|
||||||
|
SALESFORCE_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Slack
|
||||||
|
NEXT_PUBLIC_SLACK_ENABLED=
|
||||||
|
SLACK_CUSTOM_NAME=
|
||||||
|
SLACK_CLIENT_ID=
|
||||||
|
SLACK_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Spotify
|
||||||
|
NEXT_PUBLIC_SPOTIFY_ENABLED=
|
||||||
|
SPOTIFY_CUSTOM_NAME=
|
||||||
|
SPOTIFY_CLIENT_ID=
|
||||||
|
SPOTIFY_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Strava
|
||||||
|
NEXT_PUBLIC_STRAVA_ENABLED=
|
||||||
|
STRAVA_CUSTOM_NAME=
|
||||||
|
STRAVA_CLIENT_ID=
|
||||||
|
STRAVA_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Synology
|
||||||
|
NEXT_PUBLIC_SYNOLOGY_ENABLED=
|
||||||
|
SYNOLOGY_CUSTOM_NAME=
|
||||||
|
SYNOLOGY_CLIENT_ID=
|
||||||
|
SYNOLOGY_CLIENT_SECRET=
|
||||||
|
SYNOLOGY_WELLKNOWN_URL=
|
||||||
|
|
||||||
|
# Todoist
|
||||||
|
NEXT_PUBLIC_TODOIST_ENABLED=
|
||||||
|
TODOIST_CUSTOM_NAME=
|
||||||
|
TODOIST_CLIENT_ID=
|
||||||
|
TODOIST_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Twitch
|
||||||
|
NEXT_PUBLIC_TWITCH_ENABLED=
|
||||||
|
TWITCH_CUSTOM_NAME=
|
||||||
|
TWITCH_CLIENT_ID=
|
||||||
|
TWITCH_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# United Effects
|
||||||
|
NEXT_PUBLIC_UNITED_EFFECTS_ENABLED=
|
||||||
|
UNITED_EFFECTS_CUSTOM_NAME=
|
||||||
|
UNITED_EFFECTS_CLIENT_ID=
|
||||||
|
UNITED_EFFECTS_CLIENT_SECRET=
|
||||||
|
UNITED_EFFECTS_ISSUER=
|
||||||
|
|
||||||
|
# VK
|
||||||
|
NEXT_PUBLIC_VK_ENABLED=
|
||||||
|
VK_CUSTOM_NAME=
|
||||||
|
VK_CLIENT_ID=
|
||||||
|
VK_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Wikimedia
|
||||||
|
NEXT_PUBLIC_WIKIMEDIA_ENABLED=
|
||||||
|
WIKIMEDIA_CUSTOM_NAME=
|
||||||
|
WIKIMEDIA_CLIENT_ID=
|
||||||
|
WIKIMEDIA_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Wordpress.com
|
||||||
|
NEXT_PUBLIC_WORDPRESS_ENABLED=
|
||||||
|
WORDPRESS_CUSTOM_NAME=
|
||||||
|
WORDPRESS_CLIENT_ID=
|
||||||
|
WORDPRESS_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Yandex
|
||||||
|
NEXT_PUBLIC_YANDEX_ENABLED=
|
||||||
|
YANDEX_CUSTOM_NAME=
|
||||||
|
YANDEX_CLIENT_ID=
|
||||||
|
YANDEX_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Zitadel
|
||||||
|
NEXT_PUBLIC_ZITADEL_ENABLED=
|
||||||
|
ZITADEL_CUSTOM_NAME=
|
||||||
|
ZITADEL_CLIENT_ID=
|
||||||
|
ZITADEL_CLIENT_SECRET=
|
||||||
|
ZITADEL_ISSUER=
|
||||||
|
|
||||||
|
# Zoho
|
||||||
|
NEXT_PUBLIC_ZOHO_ENABLED=
|
||||||
|
ZOHO_CUSTOM_NAME=
|
||||||
|
ZOHO_CLIENT_ID=
|
||||||
|
ZOHO_CLIENT_SECRET=
|
||||||
|
|
||||||
|
# Zoom
|
||||||
|
NEXT_PUBLIC_ZOOM_ENABLED=
|
||||||
|
ZOOM_CUSTOM_NAME=
|
||||||
|
ZOOM_CLIENT_ID=
|
||||||
|
ZOOM_CLIENT_SECRET=
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
env_file: .env
|
||||||
|
restart: {{ linkwarden_restart_policy }}
|
||||||
|
volumes:
|
||||||
|
- {{ linkwarden_pgdata_path }}:/var/lib/postgresql/data
|
||||||
|
linkwarden:
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres
|
||||||
|
restart: {{ linkwarden_restart_policy }}
|
||||||
|
image: ghcr.io/linkwarden/linkwarden:{{ linkwarden_container_version }}
|
||||||
|
ports:
|
||||||
|
- {{ linkwarden_http_port }}:3000
|
||||||
|
volumes:
|
||||||
|
- {{ linkwarden_data_path }}:/data/data
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
- meilisearch
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.12.8
|
||||||
|
restart: {{ linkwarden_restart_policy }}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- {{ linkwarden_meili_data_path }}:/meili_data
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Mealie
|
||||||
|
|
||||||
|
Deploy Mealie recipe manager using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Mealie is a self-hosted recipe manager with meal planning, shopping lists, and nutrition tracking.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `mealie_http_port` | `9925` | Web interface port |
|
||||||
|
| `mealie_base_url` | `http://localhost:8080` | Base URL for application links and redirects |
|
||||||
|
| `mealie_data_path` | `{{ app_dir }}/data` | Application data storage path |
|
||||||
|
| `mealie_container_version` | `latest` | Mealie Docker image tag |
|
||||||
|
| `mealie_extra_env_vars` | `{}` | Additional environment variables as key-value pairs |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.mealie
|
||||||
|
vars:
|
||||||
|
mealie_base_url: "https://recipes.example.com"
|
||||||
|
```
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
app_name: mealie
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
mealie_container_name: "{{ app_name | default('mealie') }}"
|
||||||
|
mealie_container_version: latest
|
||||||
|
mealie_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
mealie_user: "{{ app_uid }}"
|
||||||
|
mealie_group: "{{ app_gid }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
mealie_http_port: 9925
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
mealie_data_path: "{{ app_dir }}/data"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
mealie_timezone: "{{ app_timezone_cc }}"
|
||||||
|
mealie_base_url: http://localhost:8080
|
||||||
|
mealie_extra_env_vars: {}
|
||||||
|
# ALLOW_SIGNUP: "false"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Mealie with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: mealie
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ mealie_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ mealie_data_path }}"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
mealie:
|
||||||
|
image: ghcr.io/mealie-recipes/mealie:{{ mealie_container_version }}
|
||||||
|
container_name: {{ mealie_container_name }}
|
||||||
|
restart: {{ mealie_restart_policy }}
|
||||||
|
ports:
|
||||||
|
- "{{ mealie_http_port }}:9000"
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 1000M
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- "{{ mealie_data_path }}:/app/data/"
|
||||||
|
environment:
|
||||||
|
# Set Backend ENV Variables Here
|
||||||
|
PUID: {{ mealie_user }}
|
||||||
|
PGID: {{ mealie_group }}
|
||||||
|
TZ: {{ mealie_timezone }}
|
||||||
|
BASE_URL: {{ mealie_base_url }}
|
||||||
|
{% for item in mealie_extra_env_vars %}
|
||||||
|
{{ item.key }}: {{ item.value }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Navidrome
|
||||||
|
|
||||||
|
Deploy Navidrome music streaming server using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Navidrome is a modern music server compatible with Subsonic/Airsonic clients, with web interface and mobile app support.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `navidrome_libraries` | `[]` | List of music library mappings with `host_path` and `container_path` |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `navidrome_http_port` | `4533` | Web interface port |
|
||||||
|
| `navidrome_data_path` | `{{ app_dir }}/data` | Database and application data storage |
|
||||||
|
| `navidrome_base_url` | `""` | Base URL if accessing through reverse proxy |
|
||||||
|
| `navidrome_container_version` | `latest` | Navidrome Docker image tag |
|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.navidrome
|
||||||
|
vars:
|
||||||
|
navidrome_libraries:
|
||||||
|
- host_path: /storage/music
|
||||||
|
container_path: /music
|
||||||
|
```
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
app_name: navidrome
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
navidrome_container_name: "{{ app_name | default('navidrome') }}"
|
||||||
|
navidrome_container_version: latest
|
||||||
|
navidrome_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
navidrome_uid: "{{ app_uid }}"
|
||||||
|
navidrome_gid: "{{ app_gid }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
navidrome_http_port: 4533
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
navidrome_data_path: "{{ app_dir }}/data"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
navidrome_base_url: ""
|
||||||
|
navidrome_libraries: []
|
||||||
|
# - host_path: /path/to/music
|
||||||
|
# container_path: /music
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Navidrome with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: navidrome
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ navidrome_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ navidrome_data_path }}"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
navidrome:
|
||||||
|
image: deluan/navidrome:{{ navidrome_container_version }}
|
||||||
|
container_name: "{{ navidrome_container_name }}"
|
||||||
|
user: {{ navidrome_uid }}:{{ navidrome_gid }} # should be owner of volumes
|
||||||
|
restart: "{{ navidrome_restart_policy }}"
|
||||||
|
ports:
|
||||||
|
- "{{ navidrome_http_port }}:4533"
|
||||||
|
environment:
|
||||||
|
# Optional: put your config options customization here. Examples:
|
||||||
|
ND_SCANSCHEDULE: 1h
|
||||||
|
ND_LOGLEVEL: info
|
||||||
|
ND_SESSIONTIMEOUT: 24h
|
||||||
|
{% if navidrome_base_url is defined %}
|
||||||
|
ND_BASEURL: "{{ navidrome_base_url }}"
|
||||||
|
{% endif %}
|
||||||
|
volumes:
|
||||||
|
- "{{ navidrome_data_path }}:/data"
|
||||||
|
{% for item in navidrome_libraries %}
|
||||||
|
- "{{ item.host_path }}:{{ item.container_path }}:ro"
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Open WebUI
|
||||||
|
|
||||||
|
Deploy Open WebUI for LLM interactions using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Open WebUI is a user-friendly web interface for Large Language Models, compatible with OpenAI API.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `open_webui_http_port` | `5000` | Web interface port |
|
||||||
|
| `open_webui_data_path` | `{{ app_dir }}/data` | Application data storage |
|
||||||
|
| `open_webui_container_version` | `main` | Open WebUI Docker image tag |
|
||||||
|
| `open_webui_env_vars` | See defaults | Dictionary of environment variables |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.open-webui
|
||||||
|
vars:
|
||||||
|
open_webui_http_port: 8080
|
||||||
|
open_webui_env_vars:
|
||||||
|
OLLAMA_BASE_URL: http://localhost:11434
|
||||||
|
BYPASS_MODEL_ACCESS_CONTROL: "true"
|
||||||
|
```
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
app_name: open-webui
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
open_webui_container_name: "{{ app_name | default('open-webui') }}"
|
||||||
|
open_webui_container_version: main
|
||||||
|
open_webui_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
open_webui_http_port: 5000
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
open_webui_data_path: "{{ app_dir }}/data"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
open_webui_env_vars:
|
||||||
|
OLLAMA_BASE_URL: http://localhost:11434
|
||||||
|
BYPASS_MODEL_ACCESS_CONTROL: "true"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Open-WebUI with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: open-webui
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ open_webui_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ open_webui_data_path }}"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
services:
|
||||||
|
openWebUI:
|
||||||
|
image: ghcr.io/open-webui/open-webui:{{ open_webui_container_version }}
|
||||||
|
container_name: {{ open_webui_container_name }}
|
||||||
|
restart: {{ open_webui_restart_policy }}
|
||||||
|
ports:
|
||||||
|
- "{{ open_webui_http_port }}:8080"
|
||||||
|
volumes:
|
||||||
|
- "{{ open_webui_data_path }}:/app/backend/data"
|
||||||
|
|
||||||
|
{% if open_webui_env_vars | length > 0 %}
|
||||||
|
environment:
|
||||||
|
{% for item in open_webui_env_vars | dict2items %}
|
||||||
|
- {{ item.key }}={{ item.value }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Paperless-ngx
|
||||||
|
|
||||||
|
Deploy Paperless-ngx document management system using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Paperless-ngx is a document management system that transforms your physical documents into a searchable online archive.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
## Required
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `paperless_db_password` | `paperless` | PostgreSQL password |
|
||||||
|
| `paperless_consume_path` | `{{ app_dir }}/consume` | Document intake directory |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `paperless_http_port` | `8000` | Web interface port |
|
||||||
|
| `paperless_data_path` | `{{ app_dir }}/data` | Application data storage |
|
||||||
|
| `paperless_media_path` | `{{ app_dir }}/media` | Processed document storage |
|
||||||
|
| `paperless_export_path` | `{{ app_dir }}/export` | Document export directory |
|
||||||
|
| `paperless_pgdata_path` | `{{ app_dir }}/pgdata` | PostgreSQL data storage |
|
||||||
|
| `paperless_redisdata_path` | `{{ app_dir }}/redisdata` | Redis data storage |
|
||||||
|
| `paperless_container_version` | `latest` | Paperless-ngx Docker image tag |
|
||||||
|
| `paperless_db_name` | `paperless` | PostgreSQL database name |
|
||||||
|
| `paperless_db_user` | `paperless` | PostgreSQL username |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.paperless-ngx
|
||||||
|
vars:
|
||||||
|
paperless_http_port: 8080
|
||||||
|
paperless_db_password: "{{ vault_paperless_db_password }}"
|
||||||
|
paperless_consume_path: /path/to/consume
|
||||||
|
```
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
app_name: paperless-ngx
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
paperless_container_name: "{{ app_name | default('paperless-ngx') }}"
|
||||||
|
paperless_container_version: latest
|
||||||
|
paperless_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
paperless_http_port: 8000
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
paperless_data_path: "{{ app_dir }}/data"
|
||||||
|
paperless_media_path: "{{ app_dir }}/media"
|
||||||
|
paperless_export_path: "{{ app_dir }}/export"
|
||||||
|
paperless_consume_path: "{{ app_dir }}/consume"
|
||||||
|
paperless_pgdata_path: "{{ app_dir }}/pgdata"
|
||||||
|
paperless_redisdata_path: "{{ app_dir }}/redisdata"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
paperless_db_name: paperless
|
||||||
|
paperless_db_user: paperless
|
||||||
|
paperless_db_password: paperless
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Mealie with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: paperless-ngx
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ paperless_data_path }}"
|
||||||
|
- "{{ paperless_media_path }}"
|
||||||
|
- "{{ paperless_export_path}}"
|
||||||
|
- "{{ paperless_consume_path}}"
|
||||||
|
- "{{ paperless_pgdata_path}}"
|
||||||
|
- "{{ paperless_redisdata_path}}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ paperless_data_path }}"
|
||||||
|
- "{{ paperless_media_path }}"
|
||||||
|
- "{{ paperless_export_path}}"
|
||||||
|
- "{{ paperless_pgdata_path}}"
|
||||||
|
- "{{ paperless_redisdata_path}}"
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
broker:
|
||||||
|
image: docker.io/library/redis:8
|
||||||
|
restart: {{ paperless_restart_policy }}
|
||||||
|
volumes:
|
||||||
|
- "{{ paperless_redisdata_path }}:/data"
|
||||||
|
db:
|
||||||
|
image: docker.io/library/postgres:18
|
||||||
|
restart: {{ paperless_restart_policy }}
|
||||||
|
volumes:
|
||||||
|
- "{{ paperless_pgdata_path }}:/var/lib/postgresql"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: paperless
|
||||||
|
POSTGRES_USER: paperless
|
||||||
|
POSTGRES_PASSWORD: paperless
|
||||||
|
webserver:
|
||||||
|
image: ghcr.io/paperless-ngx/paperless-ngx:{{ paperless_container_version }}
|
||||||
|
restart: {{ paperless_restart_policy }}
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- broker
|
||||||
|
- gotenberg
|
||||||
|
- tika
|
||||||
|
ports:
|
||||||
|
- "{{ paperless_http_port }}:8000"
|
||||||
|
volumes:
|
||||||
|
- "{{ paperless_data_path }}:/usr/src/paperless/data"
|
||||||
|
- "{{ paperless_media_path }}:/usr/src/paperless/media"
|
||||||
|
- "{{ paperless_export_path }}:/usr/src/paperless/export"
|
||||||
|
- "{{ paperless_consume_path }}:/usr/src/paperless/consume"
|
||||||
|
environment:
|
||||||
|
COMPOSE_PROJECT_NAME: {{ app_name }}
|
||||||
|
PAPERLESS_REDIS: redis://broker:6379
|
||||||
|
PAPERLESS_DBHOST: db
|
||||||
|
PAPERLESS_TIKA_ENABLED: 1
|
||||||
|
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
|
||||||
|
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
|
||||||
|
gotenberg:
|
||||||
|
image: docker.io/gotenberg/gotenberg:8.25
|
||||||
|
restart: {{ paperless_restart_policy }}
|
||||||
|
# The gotenberg chromium route is used to convert .eml files. We do not
|
||||||
|
# want to allow external content like tracking pixels or even javascript.
|
||||||
|
command:
|
||||||
|
- "gotenberg"
|
||||||
|
- "--chromium-disable-javascript=true"
|
||||||
|
- "--chromium-allow-list=file:///tmp/.*"
|
||||||
|
tika:
|
||||||
|
image: docker.io/apache/tika:latest
|
||||||
|
restart: {{ paperless_restart_policy }}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Redlib
|
||||||
|
|
||||||
|
Deploy Redlib privacy-focused Reddit frontend using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Redlib is an alternative private front-end to Reddit, providing a clean interface without tracking.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `redlib_http_port` | `8080` | Web interface port |
|
||||||
|
| `redlib_container_version` | `latest` | Redlib Docker image tag |
|
||||||
|
| `redlib_extra_env_vars` | `{}` | Dictionary of environment variables |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.redlib
|
||||||
|
```
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
app_name: redlib
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
redlib_container_name: "{{ app_name | default('redlib') }}"
|
||||||
|
redlib_container_version: latest
|
||||||
|
redlib_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
redlib_http_port: 8080
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
redlib_extra_env_vars: {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy redlib with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: redlib
|
||||||
|
app_health_check: false # Issues with redlib healthcheck
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
redlib:
|
||||||
|
image: quay.io/redlib/redlib:{{ redlib_container_version }}
|
||||||
|
restart: {{ redlib_restart_policy }}
|
||||||
|
container_name: {{ redlib_container_name }}
|
||||||
|
ports:
|
||||||
|
- "{{ redlib_http_port }}:8080"
|
||||||
|
user: nobody
|
||||||
|
read_only: true
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
# - seccomp=seccomp-redlib.json
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
networks:
|
||||||
|
- redlib
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--spider", "-q", "--tries=1", "http://localhost:8080/settings"]
|
||||||
|
interval: 5m
|
||||||
|
timeout: 3s
|
||||||
|
{% if redlib_extra_env_vars %}
|
||||||
|
environment:
|
||||||
|
{% for item in redlib_extra_env_vars | dict2items %}
|
||||||
|
- {{ item.key }}="{{ item.value }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
networks:
|
||||||
|
redlib:
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Speedtest Tracker
|
||||||
|
|
||||||
|
Deploy Speedtest Tracker internet monitoring tool using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Speedtest Tracker runs automatic internet speed tests and tracks results over time with beautiful charts.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Required
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `speedtest_tracker_app_key` | Application key |
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `speedtest_tracker_http_port` | `8080` | HTTP web interface port |
|
||||||
|
| `speedtest_tracker_https_port` | `8443` | HTTPS web interface port |
|
||||||
|
| `speedtest_tracker_http` | `true` | Enable HTTP port mapping |
|
||||||
|
| `speedtest_tracker_https` | `false` | Enable HTTPS port mapping |
|
||||||
|
| `speedtest_tracker_config_path` | `{{ app_dir }}/config` | Configuration and database storage |
|
||||||
|
| `speedtest_tracker_container_version` | `latest` | Speedtest Tracker Docker image tag |
|
||||||
|
| `speedtest_tracker_user` | `{{ app_uid }}` | User ID for file permissions |
|
||||||
|
| `speedtest_tracker_group` | `{{ app_gid }}` | Group ID for file permissions |
|
||||||
|
| `speedtest_tracker_timezone` | `{{ app_timezone_cc }}` | Display timezone |
|
||||||
|
| `speedtest_tracker_extra_env_vars` | See defaults | Dictionary of additional environment variables |
|
||||||
|
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.speedtest-tracker
|
||||||
|
vars:
|
||||||
|
speedtest_tracker_extra_env_vars:
|
||||||
|
SPEEDTEST_SCHEDULE: "0 * * * *" # Run every hour
|
||||||
|
```
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
app_name: speedtest-tracker
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
speedtest_tracker_container_name: "{{ app_name | default('speedtest-tracker') }}"
|
||||||
|
speedtest_tracker_container_version: latest
|
||||||
|
speedtest_tracker_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
speedtest_tracker_user: "{{ app_uid }}"
|
||||||
|
speedtest_tracker_group: "{{ app_gid }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
speedtest_tracker_http_port: 8080
|
||||||
|
speedtest_tracker_https_port: 8443
|
||||||
|
speedtest_tracker_http: true
|
||||||
|
speedtest_tracker_https: false
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
speedtest_tracker_config_path: "{{ app_dir }}/config"
|
||||||
|
|
||||||
|
# App-specific configuration
|
||||||
|
speedtest_tracker_timezone: "{{ app_timezone_cc }}"
|
||||||
|
speedtest_tracker_extra_env_vars:
|
||||||
|
SPEEDTEST_SCHEDULE: "0 * * * *"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Speedtest Tracker with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: speedtest-tracker
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ speedtest_tracker_config_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ speedtest_tracker_config_path }}"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
speedtest-tracker:
|
||||||
|
image: lscr.io/linuxserver/speedtest-tracker:{{ speedtest_tracker_container_version }}
|
||||||
|
restart: {{ speedtest_tracker_restart_policy }}
|
||||||
|
container_name: {{ speedtest_tracker_container_name }}
|
||||||
|
ports:
|
||||||
|
{% if speedtest_tracker_http %}
|
||||||
|
- {{ speedtest_tracker_http_port }}:80
|
||||||
|
{% endif %}
|
||||||
|
{% if speedtest_tracker_https %}
|
||||||
|
- {{ speedtest_tracker_https_port }}:443
|
||||||
|
{% endif %}
|
||||||
|
environment:
|
||||||
|
- PUID={{ speedtest_tracker_user }}
|
||||||
|
- PGID={{ speedtest_tracker_group }}
|
||||||
|
- APP_KEY={{ speedtest_tracker_app_key }}
|
||||||
|
- DISPLAY_TIMEZONE={{ speedtest_tracker_timezone }}
|
||||||
|
{% for item in speedtest_tracker_extra_env_vars | dict2items %}
|
||||||
|
- {{ item.key }}="{{ item.value }}"
|
||||||
|
{% endfor %}
|
||||||
|
volumes:
|
||||||
|
- {{ speedtest_tracker_config_path }}:/config
|
||||||
|
{% if speedtest_tracker_ssl_path is defined %}
|
||||||
|
- {{ speedtest_tracker_ssl_path }}:/config/keys
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Uptime Kuma
|
||||||
|
|
||||||
|
Deploy Uptime Kuma monitoring tool using Docker Compose.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Uptime Kuma is a fancy self-hosted monitoring tool with notifications and status pages.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `uptime_kuma_http_port` | `3001` | Web interface port |
|
||||||
|
| `uptime_kuma_data_path` | `{{ app_dir }}/data` | Application data storage |
|
||||||
|
| `uptime_kuma_container_version` | `2` | Uptime Kuma Docker image tag |
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- role: patrickj.docker_apps.uptime-kuma
|
||||||
|
vars:
|
||||||
|
uptime_kuma_http_port: 3002
|
||||||
|
```
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
app_name: uptime-kuma
|
||||||
|
|
||||||
|
# Container configuration
|
||||||
|
uptime_kuma_container_name: "{{ app_name | default('uptime-kuma') }}"
|
||||||
|
uptime_kuma_container_version: 2
|
||||||
|
uptime_kuma_restart_policy: "{{ app_restart_policy }}"
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
uptime_kuma_http_port: 3001
|
||||||
|
|
||||||
|
# Volume paths
|
||||||
|
uptime_kuma_data_path: "{{ app_dir }}/data"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Patrick Jaroszewski
|
||||||
|
description: Deploy Uptime Kuma with Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: patrickj.docker_apps.docker_compose_app
|
||||||
|
vars:
|
||||||
|
app_role_name: uptime-kuma
|
||||||
|
app_subdirectories:
|
||||||
|
- "{{ uptime_kuma_data_path }}"
|
||||||
|
app_backup_subdirectories:
|
||||||
|
- "{{ uptime_kuma_data_path }}"
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
uptime-kuma:
|
||||||
|
image: louislam/uptime-kuma:{{ uptime_kuma_container_version }}
|
||||||
|
container_name: "{{ uptime_kuma_container_name }}"
|
||||||
|
restart: "{{ uptime_kuma_restart_policy }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ uptime_kuma_data_path }}:/app/data"
|
||||||
|
ports:
|
||||||
|
- "{{ uptime_kuma_http_port }}:3001"
|
||||||
Reference in New Issue
Block a user