Compare commits
12 Commits
3150bf5c2c
...
df996e5ef7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df996e5ef7 | ||
|
|
5204ee38c2 | ||
|
|
88e32f216a | ||
|
|
3db21c6a05 | ||
|
|
9551382693 | ||
|
|
f45f7d25e0 | ||
|
|
3c670d5832 | ||
|
|
5a9c982f69 | ||
|
|
4c6363cab0 | ||
|
|
a58c5bd47b | ||
|
|
d77111e2fd | ||
|
|
d92d72f18f |
@@ -1,60 +1 @@
|
|||||||
# Required variables
|
Please see `roles/container/meta/arguments_specs.yml` for all possible variables
|
||||||
These variables are required. Example values included. Some general variables might also be required for this role.
|
|
||||||
|
|
||||||
```
|
|
||||||
docker_service: gitea
|
|
||||||
docker_image: gitea/gitea:latest
|
|
||||||
|
|
||||||
ports:
|
|
||||||
gitea:
|
|
||||||
http: 8080 # ports[docker_service].http (or https) needed for reverse proxy
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
# Variables for http reverse proxy
|
|
||||||
|
|
||||||
```
|
|
||||||
reverse_proxy_type: caddy # Defaults to caddy, set to none if no reverse proxy is needed. Supported values: none, caddy, traefik
|
|
||||||
docker_image_http_port: 3000 # the port used inside the container for http
|
|
||||||
|
|
||||||
docker_vhost_domains:
|
|
||||||
gitea:
|
|
||||||
- git.domain.tld
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
# Other optional variables
|
|
||||||
|
|
||||||
```
|
|
||||||
docker_service_suffix: production # For running multiple instances of the same service
|
|
||||||
|
|
||||||
docker_host_user: true # Creates a user on the host and makes the docker container use the same uid/gid. Bind mount volume directories will be owned by this user
|
|
||||||
|
|
||||||
docker_database: postgres # Database to set up in a separate container, supports postgres, mariadb and mongo
|
|
||||||
database_passwords: # Needed for postgres and mariadb
|
|
||||||
gitea: secret
|
|
||||||
|
|
||||||
docker_additional_services:
|
|
||||||
- memcached
|
|
||||||
|
|
||||||
docker_volumes:
|
|
||||||
- name: data
|
|
||||||
path: /data
|
|
||||||
- src: /var/lib/gitea/.ssh
|
|
||||||
path: /data/git/.ssh
|
|
||||||
|
|
||||||
docker_published_ports:
|
|
||||||
- "127.0.0.1:{{ ports.gitea.ssh }}:22"
|
|
||||||
docker_env:
|
|
||||||
USER_UID: 2132
|
|
||||||
GITEA__database__DB_TYPE: postgres
|
|
||||||
|
|
||||||
docker_network_mode: host # Usually you don't want to define this
|
|
||||||
|
|
||||||
dockerfile: # For building a custom container image locally
|
|
||||||
run:
|
|
||||||
- "apt-get update && apt-get install -y libmemcached-dev zlib1g-dev && pecl install memcached-3.2.0 && docker-php-ext-enable memcached"
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
docker_service_name: "{{ docker_service }}"
|
|
||||||
|
|
||||||
docker_host_user: false
|
docker_host_user: false
|
||||||
|
|
||||||
reverse_proxy_type: caddy
|
|
||||||
docker_proxy_target_protocol: http
|
|
||||||
docker_volume_type: named
|
docker_volume_type: named
|
||||||
|
|
||||||
docker_additional_env: {}
|
|
||||||
docker_published_ports: []
|
|
||||||
|
|||||||
108
roles/container/meta/argument_specs.yml
Normal file
108
roles/container/meta/argument_specs.yml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
argument_specs:
|
||||||
|
main:
|
||||||
|
short_description: Docker container
|
||||||
|
description: "Sets up a docker container. Supports defining networks, building a custom image, setting up memcached, databases and a reverse proxy, creating a user on the host to run the container as, named volumes, bind mounts (either auto-created or existing)."
|
||||||
|
options:
|
||||||
|
docker_service:
|
||||||
|
description: "The name of the docker service (example: gitea)"
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
docker_service_suffix:
|
||||||
|
description: "A suffix used to allow running multiple instances of the same service on a host. If docker_service is gitea and docker_service_suffix production, the container will be gitea_production"
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
docker_image:
|
||||||
|
description: "Docker image to use for the container. If dockerfile is defined, it will be used as base for locally built image (example: gitea/gitea:latest)"
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
docker_host_user:
|
||||||
|
description: "If true, creates a user on the host for this service. The container will run as this user's uid/gid. Bind mount volumes will be owned by this user."
|
||||||
|
type: bool
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
|
||||||
|
docker_database:
|
||||||
|
description: "Database type to set up. It will be run in a docker container accessible to the service at host <service name (with _suffix if suffix is defined)>_db on default port."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
choices:
|
||||||
|
- postgres
|
||||||
|
- mariadb
|
||||||
|
- mongodb
|
||||||
|
- none
|
||||||
|
default: none
|
||||||
|
databse_passwords:
|
||||||
|
description: "database_passwords[docker_service] is a string with the password used for communication between the service and database. Required if docker_database is postgres or mariadb"
|
||||||
|
type: dict
|
||||||
|
required: false
|
||||||
|
docker_additional_services:
|
||||||
|
description: "List of additional services to configure (in separate containers). These will be accessible with hostname <docker_service_name>[_suffix]_<additional_service>"
|
||||||
|
type: list
|
||||||
|
required: false
|
||||||
|
elements: str
|
||||||
|
choices:
|
||||||
|
- memcached
|
||||||
|
default: []
|
||||||
|
|
||||||
|
docker_volume_type:
|
||||||
|
description: "Defines whether to use named volumes or bind mounts for volume definitions with name"
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
choices:
|
||||||
|
- named
|
||||||
|
- bind
|
||||||
|
default: named
|
||||||
|
docker_volumes:
|
||||||
|
description: "List of docker volumes to be mounted inside the container. Each element is a dict with path and exactly one of name, src, template or rclone."
|
||||||
|
type: list
|
||||||
|
required: false
|
||||||
|
default: []
|
||||||
|
elements: dict
|
||||||
|
options:
|
||||||
|
path:
|
||||||
|
description: "The path inside the container to mount at"
|
||||||
|
type: str
|
||||||
|
required: true
|
||||||
|
name:
|
||||||
|
description: "If docker_volume_type is named, the name of the named volume to be mounted at path. If docker_volume_type is bind, the name of the folder to create under /opt/<service>[/suffix]/mounts/ and mount at path."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
src:
|
||||||
|
description: "Host path to bind mount inside the container."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
template:
|
||||||
|
description: "Name of template without .j2 extension. Will be templated at /opt/<service>[/suffix]/mounts/<template> and mounted inside the container."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
rclone:
|
||||||
|
description: "Name of the rclone volume to mount. Must be defined using the rclone_config variable."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
reverse_proxy_type:
|
||||||
|
description: "Defines which kind of reverse proxy to configure for the container. Traefik support is experimental."
|
||||||
|
type: str
|
||||||
|
required: false
|
||||||
|
choices:
|
||||||
|
- caddy
|
||||||
|
- traefik
|
||||||
|
- none
|
||||||
|
default: caddy
|
||||||
|
docker_image_http_port:
|
||||||
|
description: "The port for http listener inside the container. Will be mapped to the host port defined in ports. Required if reverse_proxy_type is not none."
|
||||||
|
type: int
|
||||||
|
required: false
|
||||||
|
ports:
|
||||||
|
description: "ports[docker_service]['http'] or ports[docker_service]['https'] defines the port on which the container will listen on for reverse proxy connections. Required if reverse_proxy_type is caddy."
|
||||||
|
type: dict
|
||||||
|
required: false
|
||||||
|
docker_vhost_domains:
|
||||||
|
description: "docker_vhost_domains[docker_service] is a list which defines which domains should be proxied to the container. Required if reverse_proxy_type is not none"
|
||||||
|
|
||||||
|
docker_published_ports:
|
||||||
|
description: "A list of published ports in docker format (<host listen address>:<host port>:<container port>)"
|
||||||
|
type: list
|
||||||
|
required: false
|
||||||
|
default: []
|
||||||
47
roles/container/tasks/database.yml
Normal file
47
roles/container/tasks/database.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Set postgres container vars
|
||||||
|
set_fact:
|
||||||
|
db_container_image: 'postgres:14-alpine'
|
||||||
|
db_container_env:
|
||||||
|
POSTGRES_USER: "{{ docker_service_name }}"
|
||||||
|
POSTGRES_PASSWORD: "{{ database_passwords[docker_service_name] }}"
|
||||||
|
db_container_data: /var/lib/postgresql/data
|
||||||
|
when: docker_database == 'postgres'
|
||||||
|
|
||||||
|
- name: Set mariadb container vars
|
||||||
|
set_fact:
|
||||||
|
db_container_image: mariadb:10
|
||||||
|
db_container_env:
|
||||||
|
MARIADB_USER: "{{ docker_service_name }}"
|
||||||
|
MARIADB_DATABASE: "{{ docker_service_name }}"
|
||||||
|
MARIADB_PASSWORD: "{{ database_passwords[docker_service_name] }}"
|
||||||
|
MARIADB_RANDOM_ROOT_PASSWORD: "{{ database_passwords[docker_service_name + '_root'] is not defined | string }}"
|
||||||
|
MARIADB_ROOT_PASSOWRD: "{{ database_passwords[docker_service_name + '_root'] | default(omit) }}"
|
||||||
|
db_container_data: /var/lib/mysql
|
||||||
|
db_image_port: 3306
|
||||||
|
when: docker_database == 'mariadb'
|
||||||
|
|
||||||
|
- name: Set mongo container vars
|
||||||
|
set_fact:
|
||||||
|
db_container_image: 'mongo:latest'
|
||||||
|
db_container_data: /data/db
|
||||||
|
when: docker_database == 'mongo'
|
||||||
|
|
||||||
|
- name: Set db published ports var
|
||||||
|
set_fact:
|
||||||
|
db_published_ports: ["127.0.0.1:{{ ports[docker_service_name].db }}:{{ db_image_port }}"]
|
||||||
|
when: ports[docker_service_name].db is defined
|
||||||
|
|
||||||
|
- name: Database container for {{ docker_service_name + ' (' + docker_database + ')' }}
|
||||||
|
docker_container:
|
||||||
|
name: "{{ docker_service_name }}_db"
|
||||||
|
image: "{{ db_container_image }}"
|
||||||
|
pull: true
|
||||||
|
env: "{{ db_container_env | default(omit) }}"
|
||||||
|
published_ports: "{{ db_published_ports | default(omit) }}"
|
||||||
|
restart_policy: always
|
||||||
|
volumes:
|
||||||
|
- "{{ docker_service_name }}_db:{{ db_container_data }}"
|
||||||
|
networks: "{{ container_networks | default(omit) }}"
|
||||||
|
log_driver: local
|
||||||
14
roles/container/tasks/host_user.yml
Normal file
14
roles/container/tasks/host_user.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: "Create user for {{ docker_service_name }}"
|
||||||
|
user:
|
||||||
|
name: "{{ docker_service_name }}"
|
||||||
|
home: "/opt/{{ docker_service }}/{{ docker_service_suffix | default('') }}"
|
||||||
|
create_home: false
|
||||||
|
system: true
|
||||||
|
shell: /bin/bash
|
||||||
|
register: user
|
||||||
|
|
||||||
|
- name: Set docker container user
|
||||||
|
set_fact:
|
||||||
|
docker_user: "{{ user.uid }}:{{ user.group }}"
|
||||||
41
roles/container/tasks/image.yml
Normal file
41
roles/container/tasks/image.yml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Image build
|
||||||
|
when: dockerfile is defined and dockerfile | length > 0
|
||||||
|
block:
|
||||||
|
- name: Put dockerfile in place
|
||||||
|
template:
|
||||||
|
src: Dockerfile.j2
|
||||||
|
dest: "/opt/{{ docker_service }}/Dockerfile"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Build docker image for {{ docker_service }}
|
||||||
|
docker_image:
|
||||||
|
name: "local_{{ docker_service }}"
|
||||||
|
source: build
|
||||||
|
force_source: true
|
||||||
|
build:
|
||||||
|
pull: true
|
||||||
|
path: "/opt/{{ docker_service }}"
|
||||||
|
register: built_image
|
||||||
|
|
||||||
|
- name: Pull container image for {{ docker_service }}
|
||||||
|
docker_image:
|
||||||
|
name: "{{ docker_image }}"
|
||||||
|
source: pull
|
||||||
|
force_source: true
|
||||||
|
register: pulled_image
|
||||||
|
when: dockerfile is not defined or dockerfile | length == 0
|
||||||
|
|
||||||
|
- name: Set container_image variable
|
||||||
|
set_fact:
|
||||||
|
container_image: "{{ item }}"
|
||||||
|
when: item.skipped is not defined or not item.skipped
|
||||||
|
loop:
|
||||||
|
- "{{ built_image }}"
|
||||||
|
- "{{ pulled_image }}"
|
||||||
|
|
||||||
|
- name: Set image user variable
|
||||||
|
set_fact:
|
||||||
|
image_user: "{{ container_image.image.Config.User }}"
|
||||||
|
when: container_image.image.Config.User | length > 0
|
||||||
33
roles/container/tasks/init.yml
Normal file
33
roles/container/tasks/init.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Reset variables
|
||||||
|
set_fact:
|
||||||
|
docker_volume_definition: []
|
||||||
|
container_published_ports: []
|
||||||
|
final_docker_volumes: "{{ docker_volumes }}"
|
||||||
|
|
||||||
|
- name: Set docker service full name
|
||||||
|
set_fact:
|
||||||
|
docker_service_name: "{{ docker_service }}_{{ docker_service_suffix }}"
|
||||||
|
when: docker_service_suffix is defined
|
||||||
|
|
||||||
|
- name: Convert docker_volumes from legacy format
|
||||||
|
when: docker_volumes | length > 0 and docker_volumes[0] is not mapping
|
||||||
|
block:
|
||||||
|
- name: Warn about docker_volumes legacy format
|
||||||
|
debug:
|
||||||
|
msg: "docker_volumes is set in a legacy, deprecated format. This support may be removed after december 2022."
|
||||||
|
|
||||||
|
- name: Add legacy docker volumes to docker_volumes_new using the new format
|
||||||
|
set_fact:
|
||||||
|
docker_volumes_new: "{{ docker_volumes_new | default([]) + [{'name': item.split(':')[0], 'path': item.split(':')[1]}] }}"
|
||||||
|
when: "'/' not in item.split(':')[0]"
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
- name: Add legacy docker src bind mounts to docker_volumes_new using the new format
|
||||||
|
set_fact:
|
||||||
|
docker_volumes_new: "{{ docker_volumes_new | default([]) + [{'src': item.split(':')[0], 'path': item.split(':')[1]}] }}"
|
||||||
|
when: "'/' in item.split(':')[0]"
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
- name: Set final_docker_volumes variable
|
||||||
|
set_fact:
|
||||||
|
final_docker_volumes: "{{ docker_volumes_new }}"
|
||||||
@@ -1,106 +1,32 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: Set docker service full name
|
- name: Container role initialization
|
||||||
set_fact:
|
import_tasks: init.yml
|
||||||
docker_service_name: "{{ docker_service }}_{{ docker_service_suffix }}"
|
|
||||||
when: docker_service_suffix is defined
|
|
||||||
|
|
||||||
- name: Convert docker_volumes from legacy format
|
- name: Docker network
|
||||||
when: docker_volumes is defined and docker_volumes[0] is not mapping
|
when: docker_network_mode is not defined or docker_network_mode != 'host' or docker_networks | length > 0
|
||||||
block:
|
block:
|
||||||
- name: Warn about docker_volumes legacy format
|
- name: Set networks variable to {{ docker_service_name }}
|
||||||
debug:
|
|
||||||
msg: "docker_volumes is set in a legacy, deprecated format. This support may be removed after december 2022."
|
|
||||||
|
|
||||||
- name: Add legacy docker volumes to docker_volumes_new using the new format
|
|
||||||
set_fact:
|
|
||||||
docker_volumes_new: "{{ docker_volumes_new | default([]) + [{'name': item.split(':')[0], 'path': item.split(':')[1]}] }}"
|
|
||||||
when: "'/' not in item.split(':')[0]"
|
|
||||||
loop: "{{ docker_volumes }}"
|
|
||||||
- name: Add legacy docker src bind mounts to docker_volumes_new using the new format
|
|
||||||
set_fact:
|
|
||||||
docker_volumes_new: "{{ docker_volumes_new | default([]) + [{'src': item.split(':')[0], 'path': item.split(':')[1]}] }}"
|
|
||||||
when: "'/' in item.split(':')[0]"
|
|
||||||
loop: "{{ docker_volumes }}"
|
|
||||||
- name: Set final_docker_volumes variable
|
|
||||||
set_fact:
|
|
||||||
final_docker_volumes: "{{ docker_volumes_new }}"
|
|
||||||
|
|
||||||
- name: Docker network {{ docker_service_name }}
|
|
||||||
docker_network:
|
|
||||||
name: "{{ docker_service_name }}"
|
|
||||||
when: docker_network_mode is not defined or docker_network_mode != 'host'
|
|
||||||
|
|
||||||
- name: Set networks variable
|
|
||||||
set_fact:
|
set_fact:
|
||||||
container_networks:
|
container_networks:
|
||||||
- name: "{{ docker_service_name }}"
|
- name: "{{ docker_service_name }}"
|
||||||
when: docker_network_mode is not defined or docker_network_mode != 'host'
|
when: docker_networks | length == 0
|
||||||
|
- name: Set networks variable to {{ docker_networks }}
|
||||||
- name: Reverse proxy
|
|
||||||
include_role:
|
|
||||||
name: uumas.general.reverse_proxy
|
|
||||||
vars:
|
|
||||||
vhost_id: "{{ docker_service_name }}"
|
|
||||||
proxy_target_protocol: "{{ docker_proxy_target_protocol }}"
|
|
||||||
vhost_domains: "{{ docker_vhost_domains[docker_service_name] }}"
|
|
||||||
proxy_target_port: "{{ ports[docker_service_name][proxy_target_protocol] }}"
|
|
||||||
when: reverse_proxy_type != 'none' and reverse_proxy_type != 'traefik'
|
|
||||||
|
|
||||||
- name: Set published ports variable
|
|
||||||
set_fact:
|
set_fact:
|
||||||
container_published_ports: ["127.0.0.1:{{ ports[docker_service_name][docker_proxy_target_protocol] }}:{{ docker_image_http_port }}"]
|
container_networks: "{{ docker_networks }}"
|
||||||
when: reverse_proxy_type != 'traefik' and (docker_network_mode is not defined or docker_network_mode != 'host')
|
when: docker_networks | length > 0
|
||||||
|
- name: Create docker networks
|
||||||
|
docker_network:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
loop: "{{ container_networks }}"
|
||||||
|
|
||||||
- name: Include traefik vars
|
- name: Reverse proxy for container
|
||||||
include_vars: traefik.yml
|
include_tasks: proxy.yml
|
||||||
when: reverse_proxy_type == 'traefik'
|
when: reverse_proxy_type != 'none'
|
||||||
|
|
||||||
- name: Database container
|
- name: Database container
|
||||||
when: docker_database is defined
|
include_tasks: database.yml
|
||||||
block:
|
when: docker_database != 'none'
|
||||||
- name: Set postgres container vars
|
|
||||||
set_fact:
|
|
||||||
db_container_image: 'postgres:14-alpine'
|
|
||||||
db_container_env:
|
|
||||||
POSTGRES_USER: "{{ docker_service_name }}"
|
|
||||||
POSTGRES_PASSWORD: "{{ database_passwords[docker_service_name] }}"
|
|
||||||
db_container_data: /var/lib/postgresql/data
|
|
||||||
when: docker_database == 'postgres'
|
|
||||||
- name: Set mariadb container vars
|
|
||||||
set_fact:
|
|
||||||
db_container_image: mariadb:10
|
|
||||||
db_container_env:
|
|
||||||
MARIADB_USER: "{{ docker_service_name }}"
|
|
||||||
MARIADB_DATABASE: "{{ docker_service_name }}"
|
|
||||||
MARIADB_PASSWORD: "{{ database_passwords[docker_service_name] }}"
|
|
||||||
MARIADB_RANDOM_ROOT_PASSWORD: "{{ database_passwords[docker_service_name + '_root'] is not defined | string }}"
|
|
||||||
MARIADB_ROOT_PASSOWRD: "{{ database_passwords[docker_service_name + '_root'] | default(omit) }}"
|
|
||||||
db_container_data: /var/lib/mysql
|
|
||||||
db_image_port: 3306
|
|
||||||
when: docker_database == 'mariadb'
|
|
||||||
- name: Set mongo container vars
|
|
||||||
set_fact:
|
|
||||||
db_container_image: 'mongo:latest'
|
|
||||||
db_container_data: /data/db
|
|
||||||
when: docker_database == 'mongo'
|
|
||||||
- name: Set db published ports var
|
|
||||||
set_fact:
|
|
||||||
db_published_ports: ["127.0.0.1:{{ ports[docker_service_name].db }}:{{ db_image_port }}"]
|
|
||||||
when: ports[docker_service_name].db is defined
|
|
||||||
|
|
||||||
- name: Database container for {{ docker_service_name + ' (' + docker_database + ')' }}
|
|
||||||
docker_container:
|
|
||||||
name: "{{ docker_service_name }}_db"
|
|
||||||
image: "{{ db_container_image }}"
|
|
||||||
pull: true
|
|
||||||
env: "{{ db_container_env | default(omit) }}"
|
|
||||||
published_ports: "{{ db_published_ports | default(omit) }}"
|
|
||||||
restart_policy: always
|
|
||||||
volumes:
|
|
||||||
- "{{ docker_service_name }}_db:{{ db_container_data }}"
|
|
||||||
networks: "{{ container_networks | default(omit) }}"
|
|
||||||
log_driver: local
|
|
||||||
|
|
||||||
- name: Additional services
|
- name: Additional services
|
||||||
when: docker_additional_services is defined
|
when: docker_additional_services is defined
|
||||||
@@ -122,104 +48,23 @@
|
|||||||
mode: 0755
|
mode: 0755
|
||||||
when: (dockerfile is defined and dockerfile | length > 0) or docker_host_user or docker_volume_type == 'bind'
|
when: (dockerfile is defined and dockerfile | length > 0) or docker_host_user or docker_volume_type == 'bind'
|
||||||
|
|
||||||
- name: Image build
|
- name: Container image
|
||||||
when: dockerfile is defined and dockerfile | length > 0
|
import_tasks: image.yml
|
||||||
block:
|
|
||||||
- name: Put dockerfile in place
|
|
||||||
template:
|
|
||||||
src: Dockerfile.j2
|
|
||||||
dest: "/opt/{{ docker_service }}/Dockerfile"
|
|
||||||
mode: 0644
|
|
||||||
|
|
||||||
- name: Build docker image for {{ docker_service }}
|
|
||||||
docker_image:
|
|
||||||
name: "local_{{ docker_service }}"
|
|
||||||
source: build
|
|
||||||
force_source: true
|
|
||||||
build:
|
|
||||||
pull: true
|
|
||||||
path: "/opt/{{ docker_service }}"
|
|
||||||
register: docker_built_image
|
|
||||||
|
|
||||||
- name: Container user
|
- name: Container user
|
||||||
|
include_tasks: host_user.yml
|
||||||
when: docker_host_user
|
when: docker_host_user
|
||||||
block:
|
|
||||||
- name: "Create user for {{ docker_service_name }}"
|
|
||||||
user:
|
|
||||||
name: "{{ docker_service_name }}"
|
|
||||||
home: "/opt/{{ docker_service }}/{{ docker_service_suffix | default('') }}"
|
|
||||||
create_home: false
|
|
||||||
system: true
|
|
||||||
shell: /bin/bash
|
|
||||||
register: user
|
|
||||||
|
|
||||||
- name: Set docker container user
|
- name: Container volumes
|
||||||
set_fact:
|
import_tasks: volumes.yml
|
||||||
docker_user: "{{ user.uid }}:{{ user.group }}"
|
|
||||||
|
|
||||||
- name: Bind mounts
|
|
||||||
when: "docker_volume_type == 'bind'"
|
|
||||||
block:
|
|
||||||
- name: Create directory /opt/{{ docker_service + '/' + docker_service_suffix }}
|
|
||||||
file:
|
|
||||||
path: "/opt/{{ docker_service }}/{{ docker_service_suffix }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ user.uid | default(omit) }}"
|
|
||||||
group: "{{ user.group | default(omit) }}"
|
|
||||||
mode: 0755
|
|
||||||
when: docker_service_suffix is defined
|
|
||||||
|
|
||||||
- name: Set docker_mounts_dir
|
|
||||||
set_fact:
|
|
||||||
docker_mounts_dir: "/opt/{{ docker_service }}/{{ docker_service_suffix }}/mounts"
|
|
||||||
when: docker_service_suffix is defined
|
|
||||||
- name: Set docker_mounts_dir
|
|
||||||
set_fact:
|
|
||||||
docker_mounts_dir: "/opt/{{ docker_service }}/mounts"
|
|
||||||
when: docker_service_suffix is not defined
|
|
||||||
|
|
||||||
- name: Create directory {{ docker_mounts_dir }}
|
|
||||||
file:
|
|
||||||
path: "{{ docker_mounts_dir }}"
|
|
||||||
state: directory
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
- name: "Create docker bind mount directories for {{ docker_service_name }}"
|
|
||||||
file:
|
|
||||||
path: "{{ docker_mounts_dir }}/{{ item.name }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ user.uid if item.set_owner is not defined or item.set_owner else omit | default(omit) }}"
|
|
||||||
group: "{{ user.group if item.set_group is not defined or item.set_group else omit | default(omit) }}"
|
|
||||||
mode: 0750
|
|
||||||
when: item.name is defined
|
|
||||||
loop: "{{ docker_volumes }}"
|
|
||||||
|
|
||||||
- name: Set docker_volume_definition for named binds
|
|
||||||
set_fact:
|
|
||||||
docker_volume_definition: "{{ docker_volume_definition | default([]) + [docker_mounts_dir + '/' + item.name + ':' + item.path] }}"
|
|
||||||
when: item.name is defined
|
|
||||||
loop: "{{ docker_volumes }}"
|
|
||||||
|
|
||||||
- name: Set docker_volume_definition for src binds
|
|
||||||
set_fact:
|
|
||||||
docker_volume_definition: "{{ docker_volume_definition | default([]) + [item.src + ':' + item.path] }}"
|
|
||||||
when: item.src is defined
|
|
||||||
loop: "{{ final_docker_volumes }}"
|
|
||||||
|
|
||||||
- name: Set docker_volume_definition for named volumes
|
|
||||||
set_fact:
|
|
||||||
docker_volume_definition: "{{ docker_volume_definition | default([]) + [item.name + ':' + item.path] }}"
|
|
||||||
when: docker_volume_type == 'named' and item.name is defined
|
|
||||||
loop: "{{ final_docker_volumes }}"
|
|
||||||
|
|
||||||
- name: "Container for {{ docker_service_name }}"
|
- name: "Container for {{ docker_service_name }}"
|
||||||
docker_container:
|
docker_container:
|
||||||
name: "{{ docker_service_name }}"
|
name: "{{ docker_service_name }}"
|
||||||
image: "{{ docker_built_image.image.Id if dockerfile is defined and not ansible_check_mode else docker_image }}"
|
image: "{{ container_image.image.Id }}"
|
||||||
user: "{{ docker_user | default(omit) }}"
|
user: "{{ docker_user if docker_host_user else omit }}"
|
||||||
pull: "{{ dockerfile is not defined }}"
|
mounts: "{{ docker_volume_definition }}"
|
||||||
volumes: "{{ docker_volume_definition | default(omit) }}"
|
published_ports: "{{ container_published_ports + docker_published_ports }}"
|
||||||
published_ports: "{{ container_published_ports | default([]) + docker_published_ports | default(omit) }}"
|
|
||||||
labels: "{{ traefik_labels | default(omit) }}"
|
labels: "{{ traefik_labels | default(omit) }}"
|
||||||
env: "{{ docker_env | combine(docker_additional_env) }}"
|
env: "{{ docker_env | combine(docker_additional_env) }}"
|
||||||
entrypoint: "{{ docker_entrypoint | default(omit) }}"
|
entrypoint: "{{ docker_entrypoint | default(omit) }}"
|
||||||
@@ -228,11 +73,3 @@
|
|||||||
networks: "{{ container_networks | default(omit) }}"
|
networks: "{{ container_networks | default(omit) }}"
|
||||||
log_driver: local
|
log_driver: local
|
||||||
register: container_out
|
register: container_out
|
||||||
|
|
||||||
- name: "Reset bind mount directory permissions"
|
|
||||||
file:
|
|
||||||
path: "{{ docker_mounts_dir }}/{{ item.name }}"
|
|
||||||
state: directory
|
|
||||||
mode: 0750
|
|
||||||
when: "docker_volume_type == 'bind' and item.name is defined"
|
|
||||||
loop: "{{ final_docker_volumes }}"
|
|
||||||
|
|||||||
22
roles/container/tasks/proxy.yml
Normal file
22
roles/container/tasks/proxy.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Reverse proxy
|
||||||
|
include_role:
|
||||||
|
name: uumas.general.reverse_proxy
|
||||||
|
vars:
|
||||||
|
vhost_id: "{{ docker_service_name }}"
|
||||||
|
proxy_target_protocol: "{{ docker_proxy_target_protocol }}"
|
||||||
|
vhost_domains: "{{ docker_vhost_domains[docker_service_name] }}"
|
||||||
|
proxy_target_port: "{{ ports[docker_service_name][proxy_target_protocol] }}"
|
||||||
|
when: reverse_proxy_type != 'traefik'
|
||||||
|
|
||||||
|
- name: Set published ports variable to http port
|
||||||
|
set_fact:
|
||||||
|
container_published_ports: ["127.0.0.1:{{ ports[docker_service_name][docker_proxy_target_protocol] }}:{{ docker_image_http_port }}"]
|
||||||
|
when:
|
||||||
|
- docker_network_mode is not defined or docker_network_mode != 'host'
|
||||||
|
- reverse_proxy_type != 'traefik'
|
||||||
|
|
||||||
|
- name: Include traefik vars
|
||||||
|
include_vars: traefik.yml
|
||||||
|
when: reverse_proxy_type == 'traefik'
|
||||||
74
roles/container/tasks/volumes.yml
Normal file
74
roles/container/tasks/volumes.yml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Create directories and put files in them
|
||||||
|
when:
|
||||||
|
- docker_volumes | length > 0
|
||||||
|
- (docker_volume_type == 'bind') or (docker_volumes | selectattr('template', 'defined') | list | length > 0)
|
||||||
|
block:
|
||||||
|
- name: Create directory /opt/{{ docker_service + '/' + docker_service_suffix }}
|
||||||
|
file:
|
||||||
|
path: "/opt/{{ docker_service }}/{{ docker_service_suffix }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ user.uid | default(omit) }}"
|
||||||
|
group: "{{ user.group | default(omit) }}"
|
||||||
|
mode: 0755
|
||||||
|
when: docker_service_suffix is defined
|
||||||
|
|
||||||
|
- name: Set docker_mounts_dir
|
||||||
|
set_fact:
|
||||||
|
docker_mounts_dir: "/opt/{{ docker_service }}/{{ docker_service_suffix }}/mounts"
|
||||||
|
when: docker_service_suffix is defined
|
||||||
|
- name: Set docker_mounts_dir
|
||||||
|
set_fact:
|
||||||
|
docker_mounts_dir: "/opt/{{ docker_service }}/mounts"
|
||||||
|
when: docker_service_suffix is not defined
|
||||||
|
|
||||||
|
- name: Create directory {{ docker_mounts_dir }}
|
||||||
|
file:
|
||||||
|
path: "{{ docker_mounts_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ user.uid | default(omit) }}"
|
||||||
|
group: "{{ user.group | default(omit) }}"
|
||||||
|
mode: 0700
|
||||||
|
- name: Define mounts directory owner
|
||||||
|
set_fact:
|
||||||
|
mount_owner: "{{ user.uid if docker_host_user else image_user | default('') }}"
|
||||||
|
mount_group: "{{ user.group if docker_host_user else '' }}"
|
||||||
|
|
||||||
|
- name: "Create docker bind mount directories for {{ docker_service_name }}"
|
||||||
|
file:
|
||||||
|
path: "{{ docker_mounts_dir }}/{{ item.name }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ mount_owner if (item.set_owner is not defined or item.set_owner) and mount_owner | length > 0 else omit }}"
|
||||||
|
group: "{{ mount_group if (item.set_group is not defined or item.set_group) and mount_group | length > 0 else omit }}"
|
||||||
|
when: item.name is defined
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
- name: Set docker_volume_definition for named binds
|
||||||
|
set_fact:
|
||||||
|
docker_volume_definition: "{{ docker_volume_definition + [{'source': docker_mounts_dir + '/' + item.name, 'target': item.path, 'type': 'bind'}] }}"
|
||||||
|
when: item.name is defined
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
|
||||||
|
- name: Template docker template mounts for {{ docker_service_name }}
|
||||||
|
template:
|
||||||
|
src: "{{ item.template }}.j2"
|
||||||
|
dest: "{{ docker_mounts_dir }}/{{ item.template }}"
|
||||||
|
when: item.template is defined
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
- name: Set docker_volume_definition for template mounts
|
||||||
|
set_fact:
|
||||||
|
docker_volume_definition: "{{ docker_volume_definition + [{'source': docker_mounts_dir + '/' + item.template, 'target': item.path, 'type': 'bind', 'read_only': true}] }}"
|
||||||
|
when: item.template is defined
|
||||||
|
loop: "{{ docker_volumes }}"
|
||||||
|
|
||||||
|
- name: Set docker_volume_definition for named volumes
|
||||||
|
set_fact:
|
||||||
|
docker_volume_definition: "{{ docker_volume_definition + [{'source': docker_service_name + '_' + item.name, 'target': item.path}] }}"
|
||||||
|
when: docker_volume_type == 'named' and item.name is defined
|
||||||
|
loop: "{{ final_docker_volumes }}"
|
||||||
|
|
||||||
|
- name: Set docker_volume_definition for src binds
|
||||||
|
set_fact:
|
||||||
|
docker_volume_definition: "{{ docker_volume_definition + [{'source': item.src, 'target': item.path}] }}"
|
||||||
|
when: item.src is defined
|
||||||
|
loop: "{{ final_docker_volumes }}"
|
||||||
@@ -1,3 +1,14 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
final_docker_volumes: "{{ docker_volumes }}"
|
docker_service_name: "{{ docker_service }}"
|
||||||
|
|
||||||
|
reverse_proxy_type: caddy
|
||||||
|
docker_proxy_target_protocol: http
|
||||||
|
|
||||||
|
docker_additional_env: {}
|
||||||
|
docker_database: none
|
||||||
|
docker_volumes: []
|
||||||
|
docker_networks: []
|
||||||
|
docker_env: {}
|
||||||
|
|
||||||
|
docker_published_ports: []
|
||||||
|
|||||||
6
roles/docker/handlers/main.yml
Normal file
6
roles/docker/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: restart docker
|
||||||
|
systemd:
|
||||||
|
name: docker.service
|
||||||
|
state: restarted
|
||||||
Reference in New Issue
Block a user