Compare commits

..

13 Commits

Author SHA1 Message Date
uumas
9a4c7c9440 container: add molecule tests 2023-07-19 10:11:49 +03:00
uumas
f99fbc0483 authentik: add smtp 2023-07-19 09:56:04 +03:00
uumas
c35c3f73a0 docker: remove molecule example comment 2023-07-19 09:55:18 +03:00
uumas
9787fbf0db docker: add buildx 2023-07-14 15:44:35 +03:00
uumas
79b8e4fa27 docker: ansible-lint 2023-07-14 15:34:29 +03:00
uumas
1596b2bfc5 docker: use uumas.general.apt_repository for apt repo 2023-07-14 15:25:26 +03:00
uumas
2fae11dd33 add authentik role 2023-07-05 16:18:18 +03:00
uumas
d32706bae6 grafana: fix argspec descriptions 2023-07-05 16:10:31 +03:00
uumas
195210346b container: add support for redis 2023-07-05 16:10:31 +03:00
uumas
3f5b6c0558 container: Initialize container_networks to an empty list 2023-07-05 16:10:31 +03:00
uumas
4b7a359663 container: make additional containers use only first docker network 2023-07-05 16:10:30 +03:00
uumas
4d9edf1532 container: make dockerfile variable officially supported and more modular 2023-07-05 16:10:07 +03:00
uumas
8812459beb alpine: add dockerfile to argspec 2023-07-05 15:33:54 +03:00
24 changed files with 348 additions and 54 deletions

View File

@@ -8,6 +8,6 @@ readme: README.md
repository: https://git.uumas.fi/uumas/ansible-docker repository: https://git.uumas.fi/uumas/ansible-docker
license_file: LICENSE license_file: LICENSE
dependencies: dependencies:
uumas.general: '>=0.5.8' uumas.general: '>=0.5.9'
authors: authors:
- uumas - uumas

View File

@@ -36,4 +36,6 @@ argument_specs:
docker_entrypoint: docker_entrypoint:
description: "Passed to container role" description: "Passed to container role"
required: false required: false
dockerfile:
description: "Passed to container role"
required: false

View File

@@ -0,0 +1 @@
Sets up an authentik docker container.

View File

@@ -0,0 +1,5 @@
---
authentik_env: {}
docker_networks:
- name: authentik

View File

@@ -0,0 +1,49 @@
---
argument_specs:
main:
short_description: Authentik container
description: "Sets up an authentik docker container."
options:
authentik_env:
description: "dict of custom environment variables for authentik container"
type: dict
required: false
default: {}
# All options after this will be passed directly to the container role
docker_service_suffix:
description: "Passed to container role"
required: false
docker_host_user:
description: "Passed to container role"
required: false
database_passwords:
description: "Passed to container role"
required: false
docker_additional_services:
description: "Passed to container role"
required: false
docker_volume_type:
description: "Passed to container role"
required: false
reverse_proxy_type:
description: "Passed to container role"
required: false
ports:
description: "Passed to container role"
required: false
docker_vhost_domains:
description: "Passed to container role"
required: false
docker_entrypoint:
description: "Passed to container role"
required: false
dockerfile:
description: "Passed to container role"
required: false
docker_networks:
description: "Passed to container role"
required: false

View File

@@ -0,0 +1,26 @@
---
- name: Authentik container
ansible.builtin.import_role:
name: container
vars:
docker_service: authentik
docker_image: beryju/authentik:latest
docker_command:
- server
docker_image_http_port: 9000
docker_database: postgres
docker_additional_services:
- redis
docker_env: "{{ authentik_common_env | combine(authentik_env) }}"
- name: Authentik worker container
ansible.builtin.import_role:
name: container
vars:
docker_service: authentik_worker
docker_image: beryju/authentik:latest
docker_command:
- worker
reverse_proxy_type: none
docker_env: "{{ authentik_common_env | combine(authentik_env) }}"

View File

@@ -0,0 +1,15 @@
---
authentik_common_env:
AUTHENTIK_REDIS__HOST: authentik_redis
AUTHENTIK_POSTGRESQL__HOST: authentik_db
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: "{{ database_passwords.authentik }}"
AUTHENTIK_SECRET_KEY: "{{ authentik_secret_key }}"
AUTHENTIK_EMAIL__HOST: "{{ smtp_server }}"
AUTHENTIK_EMAIL__PORT: '587'
AUTHENTIK_EMAIL__USE_TLS: 'true'
AUTHENTIK_EMAIL__USERNAME: "{{ smtp_user | default(omit) }}"
AUTHENTIK_EMAIL__PASSWORD: "{{ smtp_pw | default(omit) }}"
AUTHENTIK_EMAIL__FROM: "{{ smtp_from }}"

View File

@@ -3,6 +3,8 @@
docker_host_user: false docker_host_user: false
docker_volume_type: named docker_volume_type: named
docker_mariadb_config: {} docker_mariadb_config: {}
docker_redis_persistence: false
dockerfile: []
docker_phpmyadmin_basicauth: true docker_phpmyadmin_basicauth: true
docker_phpmyadmin_basicauth_users: {} docker_phpmyadmin_basicauth_users: {}

View File

@@ -17,6 +17,12 @@ argument_specs:
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)" 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 type: str
required: true required: true
dockerfile:
description: "A list of dockerfile instructions to add to the base image"
type: list
elements: str
required: false
default: []
docker_host_user: 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." 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 type: bool
@@ -57,7 +63,13 @@ argument_specs:
elements: str elements: str
choices: choices:
- memcached - memcached
- redis
default: [] default: []
docker_redis_persistence:
description: Whether to save redis data to persistent storage
type: bool
required: false
default: false
docker_phpmyadmin_basicauth: docker_phpmyadmin_basicauth:
description: Whether to enable basicauth for phpmyadmin description: Whether to enable basicauth for phpmyadmin
type: bool type: bool

View File

@@ -0,0 +1,18 @@
---
- name: Converge
hosts: all
tasks:
- name: Nginx container
import_role:
name: container
vars:
docker_service: nginx
docker_image: nginx
docker_image_http_port: 80
admin_email: test@example.com
ports:
nginx:
http: 28001
docker_vhost_domains:
nginx:
- localhost

View File

@@ -0,0 +1,15 @@
---
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: bullseye
image: git.uumas.fi/uumas/molecule-testbed:bullseye-docker
command: /lib/systemd/systemd
pre_build_image: true
privileged: true
provisioner:
name: ansible
verifier:
name: ansible

View File

@@ -0,0 +1,83 @@
---
- name: Verify
hosts: all
gather_facts: false
tasks:
- name: Ensure https://localhost returns 200
ansible.builtin.uri:
url: https://localhost
validate_certs: false
return_content: true
register: get_localhost
- name: Assert caddy responded on https://localhost
ansible.builtin.assert:
that: "(get_localhost.server | split(', '))[0] == 'Caddy'"
- name: Assert nginx responded on https://localhost
ansible.builtin.assert:
that: "(get_localhost.server | split(', '))[1].startswith('nginx')"
- name: Get /opt/nginx directory info
ansible.builtin.stat:
path: /opt/nginx
register: opt_nginx_stat
- name: Assert /opt/nginx doesn't exist
ansible.builtin.assert:
that: not opt_nginx_stat.stat.exists
msg: /opt/nginx should not have been created but it was
- name: Get host passwd nginx user
ansible.builtin.getent:
database: passwd
key: nginx
fail_key: false
- name: Assert nginx user does not exist
ansible.builtin.assert:
that: getent_passwd.nginx == None
msg: "nginx user should not exist but it does ({{ getent_passwd }})"
- name: Get nginx container info
community.docker.docker_container_info:
name: nginx
register: container_out
- name: Assert container port 80 forwarded to host 28001
ansible.builtin.assert:
that:
- "container_out.container.HostConfig.PortBindings['80/tcp'] is defined"
- "container_out.container.HostConfig.PortBindings['80/tcp'][0].HostPort == '28001'"
msg: "Container port 80 not correctly forwarded to host port. Port bindings output was {{ container_out.container.HostConfig.PortBindings }}"
- name: Assert container user not set
ansible.builtin.assert:
that: container_out.container.Config.User == ""
- name: Get container image info
community.docker.docker_image_info:
name: "{{ container_out.container.Image }}"
register: container_image_out
- name: Assert nginx image not built locally
assert:
that: container_image_out.images[0].RepoTags[0] == 'nginx:latest'
msg: "Nginx image tag incorrect. It should have been nginx:latest but it was {{ container_image_out.images[0].RepoTags }}"
- name: Get docker host info
community.docker.docker_host_info:
volumes: true
register: docker_host_out
- name: Assert all containers are running
ansible.builtin.assert:
that: docker_host_out.host_info.Containers == docker_host_out.host_info.ContainersRunning
msg: There should have been {{ docker_host_out.host_info.Containers }} containers running but there were {{ docker_host_out.host_info.Containers }}
- name: Assert no extra containers were created
ansible.builtin.assert:
that: docker_host_out.host_info.Containers == 1
msg: There should have been 1 container created but there were {{ docker_host_out.host_info.Containers }}
- name: Assert no extra images were pulled
ansible.builtin.assert:
that: docker_host_out.host_info.Images == 1
msg: There should have been 1 image present but there were {{ docker_host_out.host_info.Images }}
- name: Assert no volumes were created
ansible.builtin.assert:
that: docker_host_out.volumes | length == 0
msg: There should have been no volumes present but there were {{ docker_host_out.volumes | length }}

View File

@@ -6,6 +6,49 @@
image: memcached:alpine image: memcached:alpine
pull: true pull: true
restart_policy: always restart_policy: always
networks: "{{ container_networks | default(omit) }}" networks:
- "{{ container_networks[0] }}"
log_driver: local log_driver: local
when: "'memcached' in docker_additional_services" when: "'memcached' in docker_additional_services"
- name: Redis
when: "'redis' in docker_additional_services"
block:
- name: Reset redis container mount definition var
set_fact:
redis_container_mount_definition: []
- name: Set up redis container data bind mount
when: docker_volume_type == 'bind'
block:
- name: Create redis data bind mount directory for {{ docker_service_name }}
file:
path: "{{ docker_mounts_dir }}/redis"
state: directory
- name: Set redis_container_mount_definition for redis data bind mount
set_fact:
redis_container_mount_definition:
- source: "{{ docker_mounts_dir + '/redis' }}"
target: /data
type: bind
- name: Set redis_container_mount_definition for redis data named volume
set_fact:
redis_container_mount_definition:
source: "{{ docker_service_name + '_redis' }}"
target: /data
type: volume
when: docker_volume_type == 'named'
- name: "Redis container for {{ docker_service_name }}"
docker_container:
name: "{{ docker_service_name }}_redis"
image: redis:alpine
pull: true
restart_policy: always
mounts: "{{ redis_container_mount_definition }}"
command: "{{ '--save 60 1' if docker_redis_persistence else omit }}"
networks:
- "{{ container_networks[0] }}"
log_driver: local

View File

@@ -75,7 +75,8 @@
published_ports: "{{ db_published_ports | default(omit) }}" published_ports: "{{ db_published_ports | default(omit) }}"
restart_policy: always restart_policy: always
mounts: "{{ db_container_mount_definition }}" mounts: "{{ db_container_mount_definition }}"
networks: "{{ container_networks | default(omit) }}" networks:
- "{{ container_networks[0] }}"
log_driver: local log_driver: local
- name: phpMyAdmin container for {{ docker_service_name }} - name: phpMyAdmin container for {{ docker_service_name }}
@@ -89,6 +90,7 @@
published_ports: published_ports:
- "127.0.0.1:{{ ports[docker_service_name]['phpmyadmin'] }}:80" - "127.0.0.1:{{ ports[docker_service_name]['phpmyadmin'] }}:80"
restart_policy: always restart_policy: always
networks: "{{ container_networks | default(omit) }}" networks:
- "{{ container_networks[0] }}"
log_driver: local log_driver: local
when: docker_database == 'mariadb' and ports[docker_service_name]['phpmyadmin'] is defined when: docker_database == 'mariadb' and ports[docker_service_name]['phpmyadmin'] is defined

View File

@@ -7,6 +7,7 @@
docker_volumes_new: [] docker_volumes_new: []
final_docker_volumes: "{{ docker_volumes }}" final_docker_volumes: "{{ docker_volumes }}"
container_image: '' container_image: ''
container_networks: []
- name: Warn about docker_volumes legacy format - name: Warn about docker_volumes legacy format
debug: debug:
@@ -39,7 +40,7 @@
set_fact: set_fact:
template_mounts_needed: "{{ docker_mounts | selectattr('template', 'defined') | list | length > 0 }}" template_mounts_needed: "{{ docker_mounts | selectattr('template', 'defined') | list | length > 0 }}"
volumes_needed: "{{ docker_mounts | selectattr('name', 'defined') | list | length > 0 or docker_database != 'none' }}" volumes_needed: "{{ docker_mounts | selectattr('name', 'defined') | list | length > 0 or docker_database != 'none' }}"
dockerfile_needed: "{{ dockerfile is defined and dockerfile | length > 0 }}" dockerfile_needed: "{{ dockerfile | length > 0 }}"
db_config_mounts_needed: "{{ docker_mariadb_config | length > 0 }}" db_config_mounts_needed: "{{ docker_mariadb_config | length > 0 }}"
- name: Set more assistive variables - name: Set more assistive variables
set_fact: set_fact:

View File

@@ -24,10 +24,6 @@
include_tasks: proxy.yml include_tasks: proxy.yml
when: reverse_proxy_type != 'none' when: reverse_proxy_type != 'none'
- name: Additional services
include_tasks: additional.yml
when: docker_additional_services is defined
- name: Create directory /opt/{{ docker_service }} - name: Create directory /opt/{{ docker_service }}
file: file:
path: "/opt/{{ docker_service }}" path: "/opt/{{ docker_service }}"
@@ -80,6 +76,10 @@
include_tasks: database.yml include_tasks: database.yml
when: docker_database != 'none' when: docker_database != 'none'
- name: Additional services
include_tasks: additional.yml
when: docker_additional_services is defined
- name: Container volumes - name: Container volumes
import_tasks: volumes.yml import_tasks: volumes.yml
@@ -96,7 +96,7 @@
command: "{{ docker_command | default(omit) }}" command: "{{ docker_command | default(omit) }}"
restart_policy: always restart_policy: always
network_mode: "{{ docker_network_mode | default(omit) }}" network_mode: "{{ docker_network_mode | default(omit) }}"
networks: "{{ container_networks | default(omit) }}" networks: "{{ container_networks }}"
log_driver: local log_driver: local
register: container_out register: container_out

View File

@@ -1,9 +1,6 @@
# {{ ansible_managed }} # {{ ansible_managed }}
FROM {{ docker_image }} FROM {{ docker_image }}
{% if dockerfile.run is iterable %} {% for item in dockerfile %}
{% for cmd in dockerfile.run %} {{ item }}
RUN {{ cmd }}
{% endfor %} {% endfor %}
{% endif %}

View File

@@ -1,6 +1,6 @@
--- ---
- name: restart docker - name: Restart docker
systemd: ansible.builtin.systemd:
name: docker.service name: docker.service
state: restarted state: restarted

View File

@@ -0,0 +1,5 @@
---
- name: Converge
hosts: all
roles:
- docker

View File

@@ -0,0 +1,15 @@
---
dependency:
name: galaxy
driver:
name: podman
platforms:
- name: bullseye
image: git.uumas.fi/uumas/molecule-testbed:bullseye
command: /lib/systemd/systemd
pre_build_image: true
privileged: true
provisioner:
name: ansible
verifier:
name: ansible

View File

@@ -0,0 +1,12 @@
---
- name: Verify
hosts: all
gather_facts: false
tasks:
- name: Docker hello world container
community.docker.docker_container:
name: hello-world
image: hello-world
detach: false
cleanup: true
register: docker_hello_world

View File

@@ -1,38 +1,27 @@
--- ---
- name: Install dependencies - name: Add docker apt repository
apt: ansible.builtin.import_role:
name: name: uumas.general.apt_repository
- apt-transport-https vars:
- ca-certificates repo_name: docker
- curl repo_url: https://download.docker.com/linux/{{ ansible_distribution | lower }}
- gnupg repo_key_url: https://download.docker.com/linux/debian/gpg
- lsb-release repo_arch: "{{ apt_arch }}"
update_cache: true repo_components:
- stable
- name: Set dpkg arch (amd64)
set_fact:
dpkg_arch: amd64
when: ansible_architecture == 'x86_64'
- name: Set dpkg arch (arm64)
set_fact:
dpkg_arch: arm64
when: ansible_architecture == 'aarch64'
- name: Add docker repo signing key
apt_key:
id: '9DC858229FC7DD38854AE2D88D81803C0EBFCD88'
url: 'https://download.docker.com/linux/debian/gpg'
- name: Add docker repo
apt_repository:
repo: "deb [arch={{ dpkg_arch }}] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
filename: 'docker'
mode: '644'
- name: Install docker - name: Install docker
apt: ansible.builtin.apt:
name: name:
- docker-ce - docker-ce
- docker-ce-cli - docker-ce-cli
- containerd.io - containerd.io
- docker-buildx-plugin
- python3-docker - python3-docker
- name: Ensure docker is started and enabled
ansible.builtin.systemd:
name: docker.service
state: started
enabled: true

View File

@@ -2,8 +2,8 @@
argument_specs: argument_specs:
main: main:
short_description: Alpine container short_description: Grafana
description: "Sets up an alpine docker container. This role can be used as a template for other roles using the container role." description: "Sets up a grafana docker container"
options: options:
database_passwords: database_passwords:
description: "Passed to container role" description: "Passed to container role"

View File

@@ -2,7 +2,7 @@
- name: Reset dockerfile variable - name: Reset dockerfile variable
set_fact: set_fact:
dockerfile: {} dockerfile: []
- name: Set docker service full name (required because docker_env uses it) - name: Set docker service full name (required because docker_env uses it)
set_fact: set_fact:
@@ -11,14 +11,16 @@
- name: Add memcached php extension to container - name: Add memcached php extension to container
set_fact: set_fact:
dockerfile: "{{ dockerfile | combine({'run': \ dockerfile: >
['apt-get update && apt-get install -y libmemcached-dev libssl-dev zlib1g-dev && \ "{{ dockerfile +
pecl install memcached-3.2.0 && docker-php-ext-enable memcached']}, list_merge='append') }}" ['RUN apt-get update && \
apt-get install -y libmemcached-dev libssl-dev zlib1g-dev && \
pecl install memcached-3.2.0 && docker-php-ext-enable memcached'] }}"
when: "'memcached' in docker_additional_services" when: "'memcached' in docker_additional_services"
- name: Add pdo_mysql php extension to container - name: Add pdo_mysql php extension to container
set_fact: set_fact:
dockerfile: "{{ dockerfile | combine({'run': ['docker-php-ext-install -j$(nproc) pdo_mysql']}, list_merge='append') }}" dockerfile: "{{ dockerfile + ['RUN docker-php-ext-install -j$(nproc) pdo_mysql'] }}"
when: "'pdo_mysql' in wordpress_php_extensions" when: "'pdo_mysql' in wordpress_php_extensions"
- name: Include additional volume vars - name: Include additional volume vars