Compare commits
4 commits
c11f019aae
...
d526ec382d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d526ec382d | ||
|
|
5ce2a8f737 | ||
|
|
9d1a5d1924 | ||
|
|
de947dd8a4 |
8 changed files with 358 additions and 0 deletions
60
roles/send/README.md
Normal file
60
roles/send/README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
Send
|
||||||
|
====
|
||||||
|
|
||||||
|
Deploys a self-hosted [Send](https://github.com/timvisee/send) instance
|
||||||
|
(timvisee fork of the discontinued Mozilla Send) with a Redis backend
|
||||||
|
behind Traefik, using Docker Compose.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Docker + `docker compose` plugin on the target host
|
||||||
|
- Traefik (role `digitalboard.core.traefik`) reachable via an external
|
||||||
|
Docker network named `proxy` (default)
|
||||||
|
- DNS for each entry in `send_domains` pointing at the reverse proxy
|
||||||
|
- Optional: a Garage S3 bucket if `send_storage_backend: s3`
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Important defaults (see `defaults/main.yml` for the full list):
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `send_domains` | `["send.local.test"]` | FQDNs the router accepts; first entry is the canonical BASE_URL |
|
||||||
|
| `send_image` | `registry.gitlab.com/timvisee/send:latest` | Send container image |
|
||||||
|
| `send_max_file_size` | `1073741824` | Max upload size in bytes (1 GiB) |
|
||||||
|
| `send_max_expire_seconds` | `604800` | Max share lifetime (7 d) |
|
||||||
|
| `send_storage_backend` | `local` | `local` (volume) or `s3` |
|
||||||
|
| `send_s3_*` | `""` | S3 endpoint/bucket/key/secret (when backend is `s3`) |
|
||||||
|
| `send_use_ssl` | `true` | Issue Traefik labels for the `websecure` entrypoint |
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Example Playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- hosts: send_servers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- digitalboard.core.send
|
||||||
|
```
|
||||||
|
|
||||||
|
With S3 (Garage) backend:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
send_storage_backend: s3
|
||||||
|
send_s3_endpoint: "http://{{ hostvars['backend']['garage_s3_domain'] }}"
|
||||||
|
send_s3_bucket: "send"
|
||||||
|
send_s3_access_key: "{{ lookup('digitalboard.core.garage_credentials', 'send', host='backend')['key_id'] }}"
|
||||||
|
send_s3_secret_key: "{{ lookup('digitalboard.core.garage_credentials', 'send', host='backend')['secret_key'] }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
MIT
|
||||||
53
roles/send/defaults/main.yml
Normal file
53
roles/send/defaults/main.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# defaults file for send
|
||||||
|
|
||||||
|
# Base directory configuration (inherited from base role or defined here)
|
||||||
|
docker_compose_base_dir: /etc/docker/compose
|
||||||
|
docker_volume_base_dir: /srv/data
|
||||||
|
|
||||||
|
# Send-specific configuration
|
||||||
|
send_service_name: send
|
||||||
|
send_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ send_service_name }}"
|
||||||
|
send_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ send_service_name }}"
|
||||||
|
|
||||||
|
# Service configuration
|
||||||
|
# FQDNs the send router accepts. The first entry is the canonical
|
||||||
|
# domain (used as BASE_URL); further entries cover internal *.int.*
|
||||||
|
# names so backend uploads can hit us without hairpinning via DMZ.
|
||||||
|
send_domains:
|
||||||
|
- "send.local.test"
|
||||||
|
send_image: "registry.gitlab.com/timvisee/send:latest"
|
||||||
|
send_port: 1443
|
||||||
|
send_extra_hosts: []
|
||||||
|
|
||||||
|
# Redis backend
|
||||||
|
send_redis_image: "redis:7-alpine"
|
||||||
|
send_redis_service_name: "send-redis"
|
||||||
|
|
||||||
|
# Send application configuration
|
||||||
|
# https://github.com/timvisee/send/blob/master/server/config.js
|
||||||
|
send_max_file_size: 1073741824 # 1 GiB in bytes
|
||||||
|
send_default_downloads: 1
|
||||||
|
send_max_downloads: 100
|
||||||
|
send_default_expire_seconds: 86400 # 24h
|
||||||
|
send_max_expire_seconds: 604800 # 7d
|
||||||
|
send_max_files_per_archive: 64
|
||||||
|
send_download_counts: "1,2,3,4,5,20,50,100"
|
||||||
|
send_expire_times_seconds: "300,3600,86400,604800"
|
||||||
|
|
||||||
|
# Storage backend: "local" (volume) or "s3"
|
||||||
|
send_storage_backend: "local"
|
||||||
|
|
||||||
|
# S3 backend (only used when send_storage_backend == "s3")
|
||||||
|
send_s3_endpoint: ""
|
||||||
|
send_s3_bucket: ""
|
||||||
|
send_s3_region: "us-east-1"
|
||||||
|
send_s3_access_key: ""
|
||||||
|
send_s3_secret_key: ""
|
||||||
|
send_s3_use_path_style: true
|
||||||
|
|
||||||
|
# Traefik configuration
|
||||||
|
send_traefik_network: "proxy"
|
||||||
|
send_internal_network: "send_internal"
|
||||||
|
send_use_ssl: true
|
||||||
9
roles/send/handlers/main.yml
Normal file
9
roles/send/handlers/main.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# handlers file for send
|
||||||
|
|
||||||
|
- name: restart send
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ send_docker_compose_dir }}"
|
||||||
|
state: present
|
||||||
|
recreate: always
|
||||||
122
roles/send/meta/argument_specs.yml
Normal file
122
roles/send/meta/argument_specs.yml
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
---
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Deploy timvisee/send (file-sharing) with a Redis backend via Docker Compose.
|
||||||
|
description:
|
||||||
|
- Renders a Compose stack with the C(timvisee/send) container and a
|
||||||
|
Redis companion behind Traefik. Storage can be local-disk or any
|
||||||
|
S3-compatible backend (e.g. the C(garage) role).
|
||||||
|
- Uses the shared C(*_domains) list convention so the router can
|
||||||
|
accept internal C(*.int.*) hostnames alongside the canonical
|
||||||
|
BASE_URL host.
|
||||||
|
options:
|
||||||
|
docker_compose_base_dir:
|
||||||
|
type: path
|
||||||
|
default: /etc/docker/compose
|
||||||
|
docker_volume_base_dir:
|
||||||
|
type: path
|
||||||
|
default: /srv/data
|
||||||
|
send_service_name:
|
||||||
|
type: str
|
||||||
|
default: send
|
||||||
|
send_docker_compose_dir:
|
||||||
|
type: path
|
||||||
|
send_docker_volume_dir:
|
||||||
|
type: path
|
||||||
|
|
||||||
|
send_domains:
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
default: ['send.local.test']
|
||||||
|
description:
|
||||||
|
- FQDNs the router accepts. First entry is the canonical hostname
|
||||||
|
and is used as C(BASE_URL). Further entries cover internal
|
||||||
|
C(*.int.*) names so backend uploads can hit Send without
|
||||||
|
hairpinning via the DMZ.
|
||||||
|
send_image:
|
||||||
|
type: str
|
||||||
|
default: "registry.gitlab.com/timvisee/send:latest"
|
||||||
|
send_port:
|
||||||
|
type: int
|
||||||
|
default: 1443
|
||||||
|
send_extra_hosts:
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
default: []
|
||||||
|
description: C(extra_hosts) entries injected into the send container (Docker C(host:ip) syntax).
|
||||||
|
|
||||||
|
send_redis_image:
|
||||||
|
type: str
|
||||||
|
default: "redis:7-alpine"
|
||||||
|
send_redis_service_name:
|
||||||
|
type: str
|
||||||
|
default: send-redis
|
||||||
|
|
||||||
|
send_max_file_size:
|
||||||
|
type: int
|
||||||
|
default: 1073741824
|
||||||
|
description: Max upload size in bytes. Default is 1 GiB.
|
||||||
|
send_default_downloads:
|
||||||
|
type: int
|
||||||
|
default: 1
|
||||||
|
send_max_downloads:
|
||||||
|
type: int
|
||||||
|
default: 100
|
||||||
|
send_default_expire_seconds:
|
||||||
|
type: int
|
||||||
|
default: 86400
|
||||||
|
description: Default share lifetime in seconds (24 h).
|
||||||
|
send_max_expire_seconds:
|
||||||
|
type: int
|
||||||
|
default: 604800
|
||||||
|
description: Maximum share lifetime in seconds (7 d).
|
||||||
|
send_max_files_per_archive:
|
||||||
|
type: int
|
||||||
|
default: 64
|
||||||
|
send_download_counts:
|
||||||
|
type: str
|
||||||
|
default: "1,2,3,4,5,20,50,100"
|
||||||
|
description: Comma-separated list of download-count options shown in the UI.
|
||||||
|
send_expire_times_seconds:
|
||||||
|
type: str
|
||||||
|
default: "300,3600,86400,604800"
|
||||||
|
description: Comma-separated list of expire-time options (seconds) shown in the UI.
|
||||||
|
|
||||||
|
send_storage_backend:
|
||||||
|
type: str
|
||||||
|
choices: [local, s3]
|
||||||
|
default: local
|
||||||
|
description:
|
||||||
|
- C(local) keeps uploads in a host volume. C(s3) uses an
|
||||||
|
S3-compatible backend (any of the C(send_s3_*) variables is
|
||||||
|
required when this is set).
|
||||||
|
|
||||||
|
send_s3_endpoint:
|
||||||
|
type: str
|
||||||
|
default: ''
|
||||||
|
send_s3_bucket:
|
||||||
|
type: str
|
||||||
|
default: ''
|
||||||
|
send_s3_region:
|
||||||
|
type: str
|
||||||
|
default: us-east-1
|
||||||
|
send_s3_access_key:
|
||||||
|
type: str
|
||||||
|
default: ''
|
||||||
|
send_s3_secret_key:
|
||||||
|
type: str
|
||||||
|
default: ''
|
||||||
|
send_s3_use_path_style:
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
|
description: Required for most non-AWS S3-compatible backends (Garage, MinIO).
|
||||||
|
|
||||||
|
send_traefik_network:
|
||||||
|
type: str
|
||||||
|
default: proxy
|
||||||
|
send_internal_network:
|
||||||
|
type: str
|
||||||
|
default: send_internal
|
||||||
|
send_use_ssl:
|
||||||
|
type: bool
|
||||||
|
default: true
|
||||||
14
roles/send/meta/main.yml
Normal file
14
roles/send/meta/main.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
galaxy_info:
|
||||||
|
author: digitalboard
|
||||||
|
description: Deploy a self-hosted Send (timvisee fork) instance with Redis via Docker Compose
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
min_ansible_version: "2.14"
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- send
|
||||||
|
- filesharing
|
||||||
|
- docker
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
28
roles/send/tasks/main.yml
Normal file
28
roles/send/tasks/main.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# tasks file for send
|
||||||
|
|
||||||
|
- name: Create docker compose directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ send_docker_compose_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create local upload directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ send_docker_volume_dir }}/uploads"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
when: send_storage_backend == "local"
|
||||||
|
|
||||||
|
- name: Create docker-compose file for send
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: docker-compose.yml.j2
|
||||||
|
dest: "{{ send_docker_compose_dir }}/docker-compose.yml"
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart send
|
||||||
|
|
||||||
|
- name: Start send container
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ send_docker_compose_dir }}"
|
||||||
|
state: present
|
||||||
69
roles/send/templates/docker-compose.yml.j2
Normal file
69
roles/send/templates/docker-compose.yml.j2
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
services:
|
||||||
|
{{ send_service_name }}:
|
||||||
|
image: {{ send_image }}
|
||||||
|
container_name: {{ send_service_name }}
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- {{ send_redis_service_name }}
|
||||||
|
networks:
|
||||||
|
- {{ send_traefik_network }}
|
||||||
|
- {{ send_internal_network }}
|
||||||
|
{% if send_extra_hosts is defined and send_extra_hosts | length > 0 %}
|
||||||
|
extra_hosts:
|
||||||
|
{% for host in send_extra_hosts %}
|
||||||
|
- "{{ host }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
environment:
|
||||||
|
{% if send_use_ssl %}
|
||||||
|
BASE_URL: "https://{{ send_domains[0] }}"
|
||||||
|
{% else %}
|
||||||
|
BASE_URL: "http://{{ send_domains[0] }}"
|
||||||
|
{% endif %}
|
||||||
|
REDIS_HOST: "{{ send_redis_service_name }}"
|
||||||
|
REDIS_PORT: "6379"
|
||||||
|
MAX_FILE_SIZE: "{{ send_max_file_size }}"
|
||||||
|
DEFAULT_DOWNLOADS: "{{ send_default_downloads }}"
|
||||||
|
MAX_DOWNLOADS: "{{ send_max_downloads }}"
|
||||||
|
DEFAULT_EXPIRE_SECONDS: "{{ send_default_expire_seconds }}"
|
||||||
|
MAX_EXPIRE_SECONDS: "{{ send_max_expire_seconds }}"
|
||||||
|
MAX_FILES_PER_ARCHIVE: "{{ send_max_files_per_archive }}"
|
||||||
|
DOWNLOAD_COUNTS: "{{ send_download_counts }}"
|
||||||
|
EXPIRE_TIMES_SECONDS: "{{ send_expire_times_seconds }}"
|
||||||
|
{% if send_storage_backend == "s3" %}
|
||||||
|
S3_BUCKET: "{{ send_s3_bucket }}"
|
||||||
|
S3_ENDPOINT: "{{ send_s3_endpoint }}"
|
||||||
|
S3_USE_PATH_STYLE_ENDPOINT: "{{ 'true' if send_s3_use_path_style else 'false' }}"
|
||||||
|
AWS_ACCESSKEYID: "{{ send_s3_access_key }}"
|
||||||
|
AWS_SECRETACCESSKEY: "{{ send_s3_secret_key }}"
|
||||||
|
AWS_REGION: "{{ send_s3_region }}"
|
||||||
|
{% else %}
|
||||||
|
FILE_DIR: "/uploads"
|
||||||
|
volumes:
|
||||||
|
- {{ send_docker_volume_dir }}/uploads:/uploads
|
||||||
|
{% endif %}
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.docker.network={{ send_traefik_network }}
|
||||||
|
- traefik.http.routers.{{ send_service_name }}.rule={% for d in send_domains %}Host(`{{ d }}`){% if not loop.last %} || {% endif %}{% endfor +%}
|
||||||
|
- traefik.http.services.{{ send_service_name }}.loadbalancer.server.port={{ send_port }}
|
||||||
|
{% if send_use_ssl %}
|
||||||
|
- traefik.http.routers.{{ send_service_name }}.entrypoints=websecure
|
||||||
|
- traefik.http.routers.{{ send_service_name }}.tls=true
|
||||||
|
{% else %}
|
||||||
|
- traefik.http.routers.{{ send_service_name }}.entrypoints=web
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ send_redis_service_name }}:
|
||||||
|
image: {{ send_redis_image }}
|
||||||
|
container_name: {{ send_redis_service_name }}
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- {{ send_internal_network }}
|
||||||
|
volumes:
|
||||||
|
- {{ send_docker_volume_dir }}/redis:/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
{{ send_internal_network }}:
|
||||||
|
{{ send_traefik_network }}:
|
||||||
|
external: true
|
||||||
3
roles/send/vars/main.yml
Normal file
3
roles/send/vars/main.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# vars file for send
|
||||||
Loading…
Add table
Add a link
Reference in a new issue