mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-25 03:38:59 +02:00
Optimized images and version configuration for dockerfiles
This commit is contained in:
parent
9e19a050a6
commit
b599a528b8
@ -6,7 +6,7 @@ services:
|
||||
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
|
||||
image: {{ applications[application_id].images.application }}
|
||||
image: "{{ applications[application_id].images.akaunting }}"
|
||||
build:
|
||||
context: .
|
||||
ports:
|
||||
|
@ -1,5 +1,5 @@
|
||||
images:
|
||||
application: "docker.io/akaunting/akaunting:latest"
|
||||
akaunting: "docker.io/akaunting/akaunting:latest"
|
||||
company_name: "{{primary_domain}}"
|
||||
company_email: "{{users.administrator.email}}"
|
||||
setup_admin_email: "{{users.administrator.email}}"
|
||||
|
@ -6,7 +6,7 @@ services:
|
||||
|
||||
application:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: "{{ applications[application_id].images.application }}"
|
||||
image: "{{ applications[application_id].images.baserow }}"
|
||||
container_name: baserow-application
|
||||
volumes:
|
||||
- data:/baserow/data
|
||||
|
@ -1,5 +1,5 @@
|
||||
images:
|
||||
application: "baserow/baserow:latest"
|
||||
baserow: "baserow/baserow:latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -1,9 +1,13 @@
|
||||
- name: "Create (optional) '{{ docker_compose.files.dockerfile }}'"
|
||||
template:
|
||||
src: "{{ playbook_dir }}/roles/{{ role_name }}/templates/{{ template_name }}"
|
||||
src: "{{ playbook_dir }}/roles/{{ role_name }}/templates/Dockerfile"
|
||||
dest: "{{ docker_compose.files.dockerfile }}"
|
||||
notify: docker compose project build and setup
|
||||
ignore_errors: true
|
||||
ignore_errors: false
|
||||
register: create_dockerfile_result
|
||||
failed_when:
|
||||
- create_dockerfile_result is failed
|
||||
- "'Could not find or access' not in create_dockerfile_result.msg"
|
||||
|
||||
- name: "Create (optional) '{{ docker_compose.files.env }}'"
|
||||
template:
|
||||
@ -13,7 +17,10 @@
|
||||
force: yes
|
||||
notify: docker compose project setup
|
||||
register: env_template
|
||||
ignore_errors: true
|
||||
ignore_errors: false
|
||||
failed_when:
|
||||
- env_template is failed
|
||||
- "'Could not find or access' not in env_template.msg"
|
||||
|
||||
- name: "Create (obligatoric) '{{ docker_compose.files.docker_compose }}'"
|
||||
template:
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
web:
|
||||
image: espocrm/espocrm:{{ applications[application_id].version }}
|
||||
image: "{{ applications[application_id].images.espocrm }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/"]
|
||||
@ -15,7 +15,7 @@ services:
|
||||
- data:/var/www/html
|
||||
|
||||
daemon:
|
||||
image: espocrm/espocrm:{{ applications[application_id].version }}
|
||||
image: "{{ applications[application_id].images.espocrm }}"
|
||||
restart: {{docker_restart_policy}}
|
||||
logging:
|
||||
driver: journald
|
||||
@ -25,7 +25,7 @@ services:
|
||||
- data:/var/www/html
|
||||
|
||||
websocket:
|
||||
image: espocrm/espocrm:{{ applications[application_id].version }}
|
||||
image: "{{ applications[application_id].images.espocrm }}"
|
||||
restart: {{docker_restart_policy}}
|
||||
logging:
|
||||
driver: journald
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
espocrm: "espocrm/espocrm:latest"
|
||||
users:
|
||||
administrator:
|
||||
username: "{{ users.administrator.username }}"
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
application:
|
||||
image: "friendica:{{applications.friendica.version}}"
|
||||
image: "{{ applications[application_id].images.friendica }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
volumes:
|
||||
- html:/var/www/html
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
friendica: "friendica:latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -14,7 +14,7 @@ services:
|
||||
# flag:
|
||||
# celery -A funkwhale_api.taskapp worker -l INFO --concurrency=4
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: funkwhale/api:{{applications.funkwhale.version}}
|
||||
image: "{{ applications[application_id].images.api }}"
|
||||
command: celery -A funkwhale_api.taskapp worker -l INFO --concurrency={{celeryd_concurrency}}
|
||||
environment:
|
||||
- C_FORCE_ROOT=true
|
||||
@ -26,14 +26,14 @@ services:
|
||||
|
||||
celerybeat:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: funkwhale/api:{{applications.funkwhale.version}}
|
||||
image: "{{ applications[application_id].images.api }}"
|
||||
command: celery -A funkwhale_api.taskapp beat --pidfile= -l INFO
|
||||
{% include 'templates/docker/container/depends-on-database-redis.yml.j2' %}
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
|
||||
api:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: funkwhale/api:{{applications.funkwhale.version}}
|
||||
image: "{{ applications[application_id].images.api }}"
|
||||
volumes:
|
||||
- "music:{{music_directory_path}}:ro"
|
||||
- "data:{{media_root}}"
|
||||
@ -45,7 +45,7 @@ services:
|
||||
|
||||
front:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: funkwhale/front:{{applications.funkwhale.version}}
|
||||
image: "{{ applications[application_id].images.front }}"
|
||||
depends_on:
|
||||
- api
|
||||
environment:
|
||||
@ -60,7 +60,7 @@ services:
|
||||
|
||||
typesense:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: typesense/typesense:0.24.0
|
||||
image: "{{ applications[application_id].images.typesense }}"
|
||||
volumes:
|
||||
- ./typesense/data:/data
|
||||
command: --data-dir /data --enable-cors
|
||||
|
@ -1,4 +1,7 @@
|
||||
version: "1.4.0"
|
||||
images:
|
||||
api: "funkwhale/api:1.4.0"
|
||||
front: "funkwhale/front:1.4.0"
|
||||
typesense: "typesense/typesense"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -1,4 +1,4 @@
|
||||
# FusionDirectory
|
||||
# FusionDirectory (DRAFT)
|
||||
|
||||
# Warning
|
||||
This application isn't implemented yet
|
||||
|
@ -4,7 +4,7 @@ services:
|
||||
|
||||
application:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: "gitea/gitea:{{applications.gitea.version}}"
|
||||
image: "{{ applications[application_id].images.gitea }}"
|
||||
ports:
|
||||
- "127.0.0.1:{{ports.localhost.http[application_id]}}:3000"
|
||||
- "{{ports.public.ssh[application_id]}}:22"
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest" # Use latest docker image
|
||||
images:
|
||||
gitea: "gitea/gitea:latest"
|
||||
configuration:
|
||||
repository:
|
||||
enable_push_create_user: True # Allow users to push local repositories to Gitea and have them automatically created for a user.
|
||||
|
@ -5,7 +5,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
web:
|
||||
image: "gitlab/gitlab-ee:{{applications.gitlab.version}}"
|
||||
image: "{{ applications[application_id].images.gitlab }}"
|
||||
hostname: '{{domains | get_domain(application_id)}}'
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
ports:
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
gitlab: "gitlab/gitlab-ee:latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
application:
|
||||
image: "joomla:{{applications.joomla.version}}"
|
||||
image: "{{ applications[application_id].images.joomla }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
volumes:
|
||||
- data:/var/www/html
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
joomla: "joomla:latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
application:
|
||||
image: quay.io/keycloak/keycloak:{{applications.keycloak.version}}
|
||||
image: "{{ applications[application_id].images.keycloak }}"
|
||||
container_name: {{container_name}}
|
||||
command: start {% if applications[application_id].import_realm | bool %}--import-realm{% endif %}
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
keycloak: "quay.io/keycloak/keycloak:latest"
|
||||
users:
|
||||
administrator:
|
||||
username: "{{users.administrator.username}}" # Administrator Username for Keycloak
|
||||
|
@ -4,7 +4,7 @@ services:
|
||||
|
||||
application:
|
||||
container_name: {{ application_id }}
|
||||
image: ghcr.io/ldapaccountmanager/lam:{{applications[application_id].version}}
|
||||
image: "{{ applications[application_id].images.lam }}"
|
||||
ports:
|
||||
- 127.0.0.1:{{ports.localhost.http[application_id]}}:80
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
lam: "ghcr.io/ldapaccountmanager/lam:latest"
|
||||
oauth2_proxy:
|
||||
application: application
|
||||
port: 80
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-oauth2-proxy/templates/container.yml.j2' %}
|
||||
|
||||
application:
|
||||
image: bitnami/openldap:{{ applications[application_id].version }}
|
||||
image: "{{ applications[application_id].images.openldap }}"
|
||||
container_name: {{ applications[application_id].hostname }}
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
{% if applications[application_id].network.public | bool or applications[application_id].network.local | bool %}
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
openldap: "bitnami/openldap:latest"
|
||||
network:
|
||||
local: True # Activates local network. Necessary for LDIF import routines
|
||||
docker: True # Activates docker network to allow other docker containers to connect
|
||||
|
@ -4,7 +4,7 @@ services:
|
||||
|
||||
application:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: listmonk/listmonk:{{applications.listmonk.version}}
|
||||
image: "{{ applications[application_id].images.listmonk }}"
|
||||
ports:
|
||||
- "127.0.0.1:{{ports.localhost.http[application_id]}}:9000"
|
||||
volumes:
|
||||
|
@ -1,3 +1,5 @@
|
||||
images:
|
||||
listmonk: "listmonk/listmonk:latest"
|
||||
users:
|
||||
administrator:
|
||||
username: "{{users.administrator.username}}" # Listmonk administrator account username
|
||||
|
@ -5,7 +5,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
web:
|
||||
image: ghcr.io/mastodon/mastodon:{{applications.mastodon.version}}
|
||||
image: "{{ applications[application_id].images.mastodon }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||
healthcheck:
|
||||
@ -18,7 +18,7 @@ services:
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
|
||||
streaming:
|
||||
image: ghcr.io/mastodon/mastodon-streaming:{{applications.mastodon.version}}
|
||||
image: "{{ applications[application_id].images.streaming }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
command: node ./streaming
|
||||
healthcheck:
|
||||
@ -29,7 +29,7 @@ services:
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
|
||||
sidekiq:
|
||||
image: ghcr.io/mastodon/mastodon:{{applications.mastodon.version}}
|
||||
image: "{{ applications[application_id].images.mastodon }}"
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
command: bundle exec sidekiq
|
||||
{% include 'templates/docker/container/depends-on-database-redis.yml.j2' %}
|
||||
|
@ -1,4 +1,6 @@
|
||||
version: "latest"
|
||||
images:
|
||||
mastodon: "ghcr.io/mastodon/mastodon:latest"
|
||||
streaming: "ghcr.io/mastodon/mastodon-streaming:latest"
|
||||
single_user_mode: false # Set true for initial setup
|
||||
setup: false # Set true in inventory file to execute the setup and initializing procedures
|
||||
credentials:
|
||||
|
@ -4,7 +4,7 @@ services:
|
||||
|
||||
application:
|
||||
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
|
||||
image: matomo:{{applications.matomo.version}}
|
||||
image: "{{ applications[application_id].images.matomo }}"
|
||||
ports:
|
||||
- "127.0.0.1:{{ports.localhost.http.matomo}}:80"
|
||||
volumes:
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: "latest"
|
||||
images:
|
||||
matomo: "matomo:latest"
|
||||
features:
|
||||
matomo: true
|
||||
css: false
|
||||
|
@ -3,7 +3,7 @@ services:
|
||||
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
|
||||
|
||||
synapse:
|
||||
image: matrixdotorg/synapse:{{applications[application_id].synapse.version}}
|
||||
image: "{{ applications[application_id].images.synapse }}"
|
||||
container_name: matrix-synapse
|
||||
restart: {{docker_restart_policy}}
|
||||
logging:
|
||||
@ -36,7 +36,7 @@ services:
|
||||
{% endif %}
|
||||
{% include 'templates/docker/container/networks.yml.j2' %}
|
||||
element:
|
||||
image: vectorim/element-web:{{applications[application_id].element.version}}
|
||||
image: "{{ applications[application_id].images.element }}"
|
||||
container_name: matrix-element
|
||||
restart: {{docker_restart_policy}}
|
||||
volumes:
|
||||
|
@ -1,4 +1,7 @@
|
||||
|
||||
images:
|
||||
synapse: "matrixdotorg/synapse:latest"
|
||||
element: "vectorim/element-web:latest"
|
||||
# Set bridges
|
||||
users:
|
||||
administrator:
|
||||
username: "{{users.administrator.username}}" # Accountname of the matrix admin
|
||||
|
2
roles/docker-pixelfed/Todo.md
Normal file
2
roles/docker-pixelfed/Todo.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Todo
|
||||
- Integrate OIDC as soon as possible
|
49
tests/integration/test_deprecated_version_key.py
Normal file
49
tests/integration/test_deprecated_version_key.py
Normal file
@ -0,0 +1,49 @@
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
class TestDeprecatedVersionKey(unittest.TestCase):
|
||||
def test_version_key_deprecation(self):
|
||||
"""
|
||||
Checks all roles/docker-*/vars/configuration.yml for deprecated use of 'version'.
|
||||
Warns if 'version' is set but 'images' is missing.
|
||||
Prints warnings but does NOT fail the test.
|
||||
"""
|
||||
repo_root = Path(__file__).resolve().parent.parent.parent
|
||||
roles_dir = repo_root / "roles"
|
||||
warnings = []
|
||||
|
||||
for role_path in roles_dir.iterdir():
|
||||
if not (role_path.is_dir() and role_path.name.startswith("docker-")):
|
||||
continue
|
||||
|
||||
cfg_file = role_path / "vars" / "configuration.yml"
|
||||
if not cfg_file.exists():
|
||||
continue
|
||||
|
||||
try:
|
||||
config = yaml.safe_load(cfg_file.read_text("utf-8")) or {}
|
||||
except yaml.YAMLError as e:
|
||||
print(f"YAML parse error in {cfg_file}: {e}")
|
||||
continue
|
||||
|
||||
uses_version = 'version' in config
|
||||
uses_images = 'images' in config
|
||||
|
||||
if uses_version and not uses_images:
|
||||
warnings.append(
|
||||
f"[DEPRECATION WARNING] {role_path.name}/vars/configuration.yml: "
|
||||
f"'version:' is set, but 'images:' is missing. "
|
||||
f"'version' is deprecated and must only be set if 'images' is present."
|
||||
)
|
||||
|
||||
if warnings:
|
||||
print("\n".join(warnings))
|
||||
else:
|
||||
print("No deprecated 'version:' keys found in docker roles without 'images:'.")
|
||||
|
||||
# Never fail, just warn
|
||||
self.assertTrue(True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
88
tests/integration/test_docker_images_configuration.py
Normal file
88
tests/integration/test_docker_images_configuration.py
Normal file
@ -0,0 +1,88 @@
|
||||
import unittest
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
class TestDockerRoleImagesConfiguration(unittest.TestCase):
|
||||
def test_images_keys_and_templates(self):
|
||||
"""
|
||||
For each docker-* role, check that:
|
||||
- roles/docker-*/vars/configuration.yml contains 'images' as a dict with keys/values
|
||||
- Each image key is referenced as:
|
||||
image: "{{ applications[application_id].images.<key> }}"
|
||||
in either roles/docker-*/templates/docker-compose.yml.j2 or env.j2
|
||||
"""
|
||||
repo_root = Path(__file__).resolve().parent.parent.parent
|
||||
roles_dir = repo_root / "roles"
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
for role_path in roles_dir.iterdir():
|
||||
if not (role_path.is_dir() and role_path.name.startswith("docker-")):
|
||||
continue
|
||||
|
||||
cfg_file = role_path / "vars" / "configuration.yml"
|
||||
if not cfg_file.exists():
|
||||
continue # No configuration to check
|
||||
|
||||
try:
|
||||
config = yaml.safe_load(cfg_file.read_text("utf-8")) or {}
|
||||
except yaml.YAMLError as e:
|
||||
errors.append(f"{role_path.name}: YAML parse error: {e}")
|
||||
continue
|
||||
|
||||
images = config.get("images")
|
||||
if not images:
|
||||
warnings.append(f"[WARNING] {role_path.name}: No 'images' key in configuration.yml")
|
||||
continue
|
||||
|
||||
if not isinstance(images, dict):
|
||||
errors.append(f"{role_path.name}: 'images' must be a dict in configuration.yml")
|
||||
continue
|
||||
|
||||
for key, value in images.items():
|
||||
if not key or not value or not isinstance(key, str) or not isinstance(value, str):
|
||||
errors.append(f"{role_path.name}: images['{key}'] is invalid (must be non-empty string key and value)")
|
||||
continue
|
||||
|
||||
# Improved regex: matches both ' and " and allows whitespace
|
||||
pattern = (
|
||||
r'image:\s*["\']\{\{\s*applications\[application_id\]\.images\.' + re.escape(key) + r'\s*\}\}["\']'
|
||||
)
|
||||
|
||||
found = False
|
||||
for tmpl_file in [
|
||||
role_path / "templates" / "docker-compose.yml.j2",
|
||||
role_path / "templates" / "env.j2"
|
||||
]:
|
||||
if tmpl_file.exists():
|
||||
content = tmpl_file.read_text("utf-8")
|
||||
if re.search(pattern, content):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
errors.append(
|
||||
f"{role_path.name}: image key '{key}' is not referenced as "
|
||||
f'image: \"{{{{ applications[application_id].images.{key} }}}}\" in docker-compose.yml.j2 or env.j2'
|
||||
)
|
||||
|
||||
|
||||
# OPTIONAL: Check if the image is available locally via docker images
|
||||
# from shutil import which
|
||||
# import subprocess
|
||||
# if which("docker"):
|
||||
# try:
|
||||
# out = subprocess.check_output(
|
||||
# ["docker", "images", "--format", "{{.Repository}}:{{.Tag}}"]
|
||||
# ).decode()
|
||||
# if value not in out:
|
||||
# errors.append(f"{role_path.name}: Image '{value}' not found locally (optional check)")
|
||||
# except Exception as e:
|
||||
# errors.append(f"{role_path.name}: Error running 'docker images' (optional): {e}")
|
||||
if warnings:
|
||||
print("\nWarnings in docker role images configuration:\n" + "\n".join(warnings))
|
||||
if errors:
|
||||
self.fail("Errors in docker role images configuration:\n" + "\n".join(errors))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user