commit 927667531c8fc2abd3b5799a395c0d0fcd2455fe Author: Greg Hendrickson Date: Thu Oct 19 14:17:11 2023 -0700 init repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23a4dcc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +web-apps/docker-env.env +wordpress/docker-wordpress-env.env +secret-messages/docker-secrets-env.env diff --git a/Deluge/docker-compose-deluge.yml b/Deluge/docker-compose-deluge.yml new file mode 100644 index 0000000..caf66bc --- /dev/null +++ b/Deluge/docker-compose-deluge.yml @@ -0,0 +1,19 @@ +--- +version: "2.1" +services: + deluge: + image: lscr.io/linuxserver/deluge:latest + container_name: deluge + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - DELUGE_LOGLEVEL=error #optional + volumes: + - /opt/docker/deluge/config:/config + - /opt/docker/deluge/downloads:/downloads + ports: + - 8112:8112 + - 6881:6881 + - 6881:6881/udp + restart: unless-stopped \ No newline at end of file diff --git a/Lab-grafana-prometheus-jenkins/docker-compose-lab.yml b/Lab-grafana-prometheus-jenkins/docker-compose-lab.yml new file mode 100644 index 0000000..0b23389 --- /dev/null +++ b/Lab-grafana-prometheus-jenkins/docker-compose-lab.yml @@ -0,0 +1,113 @@ +version: "3" + +# Define a custom network for the services to communicate with each other +networks: + jenk_prom_graf_lab: + driver: bridge + +# Define the services that will be run in the containers +services: + + # Grafana service + grafana: + image: grafana/grafana:latest + container_name: grafana + volumes: + # Mount the Grafana plugins directory to the container + - /opt/docker/grafana/plugins:/var/lib/grafana/plugins + # Mount the Grafana data directory to the container + - grafana_data:/opt/docker/grafana/data + ports: + # Expose the Grafana service on port 3000 + - 3000:3000 + networks: + # Connect the Grafana service to the custom network + - jenk_prom_graf_lab + restart: unless-stopped + + # Prometheus service + prometheus: + image: prom/prometheus:latest + container_name: prometheus + volumes: + # Mount the Prometheus data directory to the container + - prometheus_data:/opt/docker/prometheus/data + # Mount the Prometheus configuration directory to the container + - /opt/docker/prometheus/data/config:/etc/prometheus + command: + # Specify the Prometheus configuration file + - '--config.file=/etc/prometheus/prometheus.yml' + # Specify the Prometheus data directory + - '--storage.tsdb.path=/opt/docker/prometheus/data/config' + # Specify the Prometheus console libraries directory + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + # Specify the Prometheus console templates directory + - '--web.console.templates=/usr/share/prometheus/consoles' + ports: + # Expose the Prometheus service on port 9090 + - 9090:9090 + networks: + # Connect the Prometheus service to the custom network + - jenk_prom_graf_lab + restart: unless-stopped + + # InfluxDB service + influxdb: + image: influxdb:1.8.6-alpine + container_name: influxdb + volumes: + # Mount the InfluxDB data directory to the container + - influxdb_data:/opt/docker/influxdb/data + ports: + # Expose the InfluxDB service on port 8086 + - 8086:8086 + networks: + # Connect the InfluxDB service to the custom network + - jenk_prom_graf_lab + restart: unless-stopped + + # Jenkins service + jenkins: + image: jenkins/jenkins:lts-jdk11 + container_name: jenkins + volumes: + # Mount the Jenkins data directory to the container + - jenkins_data:/opt/docker/jenkins/data + # Mount the Jenkins plugins directory to the container + - /opt/docker/jenkins/plugins:/var/jenkins_home/plugins + ports: + # Expose the Jenkins service on port 8080 + - 8080:8080 + # Expose the Jenkins service on port 50000 + - 50000:50000 + networks: + # Connect the Jenkins service to the custom network + - jenk_prom_graf_lab + restart: unless-stopped + +# Define the volumes that will be used by the services +volumes: + jenkins_data: + driver_opts: + # Mount the Jenkins data directory as a bind mount + type: none + device: /opt/docker/jenkins/data + o: bind + grafana_data: + driver_opts: + # Mount the Grafana data directory as a bind mount + type: none + device: /opt/docker/grafana/data + o: bind + influxdb_data: + driver_opts: + # Mount the InfluxDB data directory as a bind mount + type: none + device: /opt/docker/influxdb/data + o: bind + prometheus_data: + driver_opts: + # Mount the Prometheus data directory as a bind mount + type: none + device: /opt/docker/prometheus/data + o: bind \ No newline at end of file diff --git a/Lab-grafana-prometheus-jenkins/grafana-setup.md b/Lab-grafana-prometheus-jenkins/grafana-setup.md new file mode 100644 index 0000000..b167998 --- /dev/null +++ b/Lab-grafana-prometheus-jenkins/grafana-setup.md @@ -0,0 +1,80 @@ +# Jenkins Dashboard + +## Host Online Check + +- `jenkins_node_online_value`: + - 1: up (green) + - 0: down (red) + +## Time Series Metrics + +### Number of Jenkins Executors +- `jenkins_executor_count_value` + +### Number in Queue +- `jenkins_queue_size_value` + +### Number of Nodes +- `jenkins_node_count_value` + +## Individual Stat Panels + +### Plugins Active +- `jenkins_plugins_active` + +### Inactive Plugins +- `jenkins_plugins_inactive` + +### Plugins with Updates +- `jenkins_plugins_withUpdates` + +## Set Variables in Dashboard for Dropdown + +-- SHOW TAG VALUES FROM job WITH KEY = "owner" +-- SHOW TAG VALUES FROM job WITH KEY = repo WHERE "owner" =~ /^($folder)$/ + +## Overall Panel +## Successful Build Countsz + +-- SELECT count(build_number) FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND ("build_result" = 'SUCCESS' OR "build_result" = 'CompletedSuccess' ) AND $timeFilter + +## Failed Build Counts + +-- SELECT count(build_number) FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND ("build_result" = 'FAILURE' OR "build_result" = 'CompletedError' ) AND $timeFilter + +## Aborted Build Counts + +-- SELECT count(build_number) FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND ("build_result" = 'ABORTED' OR "build_result" = 'Aborted' ) AND $timeFilter + +## Unstable Build Counts + +-- SELECT count(build_number) FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND ("build_result" = 'UNSTABLE' OR "build_result" = 'Unstable' ) AND $timeFilter + +## Number of Pipelines Ran + +-- SELECT count(DISTINCT project_name) FROM jenkins_data WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND $timeFilter + +## Total Number of Builds + +-- SELECT count(build_number) FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND $timeFilter + +## Average Build Time + +-- SELECT build_time/1000 FROM jenkins_data WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND $timeFilter + +## Latest Build Status + +-- SELECT build_result FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND $timeFilter ORDER BY time DESC LIMIT 1 + +## Build Details - Table + +-- SELECT "build_exec_time","project_path","build_number","build_causer","build_time","build_result" FROM "jenkins_data" WHERE ("project_name" =~ /^(?i)$job$/ AND "project_path" =~ /.*(?i)$folder.*$/) AND $timeFilter + + +## Data Links for Build Details Table: +http://your-ip:8080/job/${__data.fields["project_path"]}/${__data.fields["build_number"]} + + +## Value Map Regex +Find: /(/)/g +Replace with: /job$1 \ No newline at end of file diff --git a/Lab-grafana-prometheus-jenkins/image.png b/Lab-grafana-prometheus-jenkins/image.png new file mode 100644 index 0000000..0897212 Binary files /dev/null and b/Lab-grafana-prometheus-jenkins/image.png differ diff --git a/Lab-grafana-prometheus-jenkins/jenkins-dashboard-ghndrx.json b/Lab-grafana-prometheus-jenkins/jenkins-dashboard-ghndrx.json new file mode 100644 index 0000000..50bf153 --- /dev/null +++ b/Lab-grafana-prometheus-jenkins/jenkins-dashboard-ghndrx.json @@ -0,0 +1,1186 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "description": "Jenkins Status", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "0": { + "color": "red", + "index": 1, + "text": "DOWN" + }, + "1": { + "color": "green", + "index": 0, + "text": "UP" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_node_online_value", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Jenkins Status", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Success" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Failure" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Aborted" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Unstable" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 16, + "w": 6, + "x": 3, + "y": 0 + }, + "id": 6, + "options": { + "displayLabels": [ + "value", + "name" + ], + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "alias": "Success", + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "SELECT count(build_number) FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND (\"build_result\" = 'SUCCESS' OR \"build_result\" = 'CompletedSuccess' ) AND $timeFilter ", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + }, + { + "alias": "Failure", + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "hide": false, + "query": "SELECT count(build_number) FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND (\"build_result\" = 'FAILURE' OR \"build_result\" = 'CompletedError' ) AND $timeFilter ", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series" + }, + { + "alias": "Aborted", + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "hide": false, + "query": "SELECT count(build_number) FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND (\"build_result\" = 'ABORTED' OR \"build_result\" = 'Aborted' ) AND $timeFilter ", + "rawQuery": true, + "refId": "C", + "resultFormat": "time_series" + }, + { + "alias": "Unstable", + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "hide": false, + "query": "SELECT count(build_number) FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND (\"build_result\" = 'UNSTABLE' OR \"build_result\" = 'Unstable' ) AND $timeFilter ", + "rawQuery": true, + "refId": "D", + "resultFormat": "time_series" + } + ], + "title": "Overall", + "type": "piechart" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 9, + "y": 0 + }, + "id": 5, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "select count(DISTINCT project_name) FROM jenkins_data WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND $timeFilter ", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Number of Pipelines Ran", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 12, + "y": 0 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "SELECT count(build_number) FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND $timeFilter ", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Total number of builds", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "clocks" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 15, + "y": 0 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "value" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "select build_time/1000 FROM jenkins_data WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND $timeFilter ", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Average Build Time ", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 2, + "x": 18, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_plugins_active", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Active Plugins", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 2, + "x": 20, + "y": 0 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_plugins_withUpdate", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Plugins with Updates", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 2, + "x": 22, + "y": 0 + }, + "id": 3, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_plugins_inactive", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Inactive Plugins", + "type": "stat" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "ABORTED": { + "color": "yellow", + "index": 0, + "text": "Aborted" + }, + "FAILURE": { + "color": "red", + "index": 2, + "text": "Failure" + }, + "SUCCESS": { + "color": "green", + "index": 1, + "text": "Success" + }, + "UNSTABLE": { + "color": "purple", + "index": 3, + "text": "Unstable" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 0, + "y": 8 + }, + "id": 9, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^jenkins_data\\.build_result$/", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "SELECT build_result FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND $timeFilter ORDER BY time DESC LIMIT 1", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Latest Build Status", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "{__name__=\"jenkins_executor_count_value\", instance=\"10.1.10.26:8080\", job=\"jenkins\"}" + }, + "properties": [ + { + "id": "displayName", + "value": "Executor Count" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "{__name__=\"jenkins_queue_size_value\", instance=\"10.1.10.26:8080\", job=\"jenkins\"}" + }, + "properties": [ + { + "id": "displayName", + "value": "Queue Size" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "{__name__=\"jenkins_node_count_value\", instance=\"10.1.10.26:8080\", job=\"jenkins\"}" + }, + "properties": [ + { + "id": "displayName", + "value": "Node Count" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 15, + "x": 9, + "y": 8 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_executor_count_value\r\n", + "instant": false, + "interval": "", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_queue_size_value", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "eb3234ad-8489-410b-a297-cee8c2b81b16" + }, + "editorMode": "code", + "expr": "jenkins_node_count_value", + "hide": false, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C" + } + ], + "title": "Jenkins node, queue, executor stats", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "transparent", + "mode": "fixed" + }, + "custom": { + "align": "center", + "cellOptions": { + "mode": "gradient", + "type": "color-background" + }, + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.build_exec_time" + }, + "properties": [ + { + "id": "unit", + "value": "dateTimeAsUS" + }, + { + "id": "displayName", + "value": "Build Start" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.project_path" + }, + "properties": [ + { + "id": "displayName", + "value": "Pipeline Path" + }, + { + "id": "links", + "value": [ + { + "title": "Jenkins Job", + "url": "http://10.1.10.26:8080/job/${__data.fields[\"jenkins_data.project_path\"]}/${__data.fields[\"jenkins_data.build_number\"]}" + } + ] + }, + { + "id": "mappings", + "value": [ + { + "options": { + "pattern": "/(\\/)/g", + "result": { + "index": 0, + "text": "/job$1" + } + }, + "type": "regex" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.build_number" + }, + "properties": [ + { + "id": "displayName", + "value": "Build Number" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.build_causer" + }, + "properties": [ + { + "id": "displayName", + "value": "Causer" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.build_time" + }, + "properties": [ + { + "id": "displayName", + "value": "Build Time" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "jenkins_data.build_result" + }, + "properties": [ + { + "id": "displayName", + "value": "Build Result" + }, + { + "id": "mappings", + "value": [ + { + "options": { + "ABORTED": { + "color": "orange", + "index": 3, + "text": "Aborted" + }, + "FAILURE": { + "color": "red", + "index": 1, + "text": "Failure" + }, + "SUCCESS": { + "color": "green", + "index": 0, + "text": "Success" + }, + "UNSTABLE": { + "color": "purple", + "index": 2, + "text": "Unstable" + } + }, + "type": "value" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 13, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 10, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.1.5", + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "query": "SELECT \"build_exec_time\",\"project_path\",\"build_number\",\"build_causer\",\"build_time\",\"build_result\" FROM \"jenkins_data\" WHERE (\"project_name\" =~ /^(?i)$job$/ AND \"project_path\" =~ /.*(?i)$folder.*$/) AND $timeFilter ", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Build Details", + "transformations": [ + { + "id": "joinByField", + "options": {} + } + ], + "type": "table" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "definition": "SHOW TAG VALUES FROM job WITH KEY = \"owner\"\n", + "description": "folder", + "hide": 0, + "includeAll": true, + "label": "Folder", + "multi": false, + "name": "folder", + "options": [], + "query": "SHOW TAG VALUES FROM job WITH KEY = \"owner\"\n", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "influxdb", + "uid": "c9700b4e-79ba-4648-991c-de4e9525cb4e" + }, + "definition": "SHOW TAG VALUES FROM job WITH KEY = repo WHERE \"owner\" =~ /^($folder)$/", + "description": "job", + "hide": 0, + "includeAll": true, + "label": "Job", + "multi": false, + "name": "job", + "options": [], + "query": "SHOW TAG VALUES FROM job WITH KEY = repo WHERE \"owner\" =~ /^($folder)$/", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Jenkins Dashboard", + "uid": "f5583e67-c225-4b92-80e9-368d1b0a0032", + "version": 10, + "weekStart": "" + } \ No newline at end of file diff --git a/secret-messages/docker-compose.yaml b/secret-messages/docker-compose.yaml new file mode 100644 index 0000000..557949f --- /dev/null +++ b/secret-messages/docker-compose.yaml @@ -0,0 +1,46 @@ +version: '3.2' + +services: + vault: + image: hashicorp/vault:latest + container_name: vault + environment: + VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_TOKEN} + cap_add: + - IPC_LOCK + expose: + - 8200 + networks: + - traefik + + supersecret: + build: ./ + image: algolia/supersecretmessage:latest + container_name: supersecret + environment: + VAULT_ADDR: http://vault:8200 + VAULT_TOKEN: ${VAULT_TOKEN} + SUPERSECRETMESSAGE_HTTP_BINDING_ADDRESS: ":80" + SUPERSECRETMESSAGE_HTTPS_BINDING_ADDRESS: ":443" + SUPERSECRETMESSAGE_HTTPS_REDIRECT_ENABLED: "true" + SUPERSECRETMESSAGE_TLS_AUTO_DOMAIN: ${SECRET_HOST} + labels: + - "traefik.enable=true" + - "traefik.http.routers.secret-message.rule=Host(`$(SECRET_HOST)`)" + - "traefik.http.routers.secret-message.entrypoints=websecure" + - "traefik.http.routers.secret-message.tls=true" + - "traefik.http.routers.secret-message.tls.certresolver=myresolver" + - "traefik.http.routers.secret-message.middlewares=redirect-to-https" + - "traefik.http.routers.secret-message.service=secret-message" + - "traefik.http.services.secret-message.loadbalancer.server.port=80" + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + volumes: + - ${SECRET_STORAGE}:/app/data + networks: + - traefik + depends_on: + - vault + +networks: + traefik: + external: true diff --git a/secret-messages/docker-secrets-env.example b/secret-messages/docker-secrets-env.example new file mode 100644 index 0000000..b7d3c68 --- /dev/null +++ b/secret-messages/docker-secrets-env.example @@ -0,0 +1,3 @@ +SECRET_HOST=your.example.com +VAULT_TOKEN=yoursecrettoken +SECRET_STORAGE=/path/to/storage \ No newline at end of file diff --git a/web-apps/docker-compose.yml b/web-apps/docker-compose.yml new file mode 100644 index 0000000..85f110e --- /dev/null +++ b/web-apps/docker-compose.yml @@ -0,0 +1,266 @@ +version: '3' + +services: + # Traefik service for reverse proxy and SSL termination + traefik: + image: traefik:v2.4 + command: + - "--api.insecure=true" # Enable insecure API for Traefik dashboard + - "--providers.docker=true" # Enable Docker provider for Traefik + - "--providers.docker.exposedbydefault=false" # Do not expose containers by default + - "--entrypoints.web.address=:80" # HTTP entrypoint + - "--entrypoints.websecure.address=:443" # HTTPS entrypoint + - "--certificatesresolvers.myresolver.acme.email=${ACME_EMAIL}" # Email for Let's Encrypt registration + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" # Storage for Let's Encrypt certificates + - "--certificatesresolvers.myresolver.acme.httpchallenge=true" # Use HTTP challenge for Let's Encrypt + - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" # Use HTTP entrypoint for Let's Encrypt challenge + ports: + - "80:80" # Expose HTTP port + - "443:443" # Expose HTTPS port + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro # Mount Docker socket for Traefik to access Docker API + - /mnt/storage/hndrx.co/traefik/letsencrypt:/letsencrypt # Mount Let's Encrypt certificates storage + labels: + - "traefik.enable=true" # Enable Traefik for this service + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" # Redirect HTTP to HTTPS + - "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_HOST}`)" # Route Traefik dashboard to specified host + - "traefik.http.routers.traefik.entrypoints=websecure" # Use HTTPS entrypoint for Traefik dashboard + - "traefik.http.routers.traefik.tls=true" # Enable TLS for Traefik dashboard + - "traefik.http.routers.traefik.tls.certresolver=myresolver" # Use Let's Encrypt resolver for Traefik dashboard + - "traefik.http.routers.traefik.service=api@internal" # Use Traefik API for Traefik dashboard + - "traefik.http.routers.traefik.middlewares=redirect-to-https@docker" # Use redirect middleware for Traefik dashboard + networks: + - traefik # Use external network named "traefik" + + # MySQL service for Nextcloud + mysql-nextcloud: + image: mysql:latest + restart: always + environment: + MYSQL_DATABASE: ${NEXTCLOUD_DB_NAME} # Set Nextcloud database name + MYSQL_USER: ${NEXTCLOUD_DB_USER} # Set Nextcloud database user + MYSQL_ROOT_PASSWORD: ${NEXTCLOUD_DB_ROOT_PASSWORD} # Set MySQL root password + MYSQL_PASSWORD: ${NEXTCLOUD_DB_PASSWORD} # Set Nextcloud database password + hostname: mysql-nextcloud # Set hostname for MySQL container + volumes: + - /mnt/storage/mysql-nextcloud:/var/lib/mysql # Mount MySQL data directory + networks: + - traefik # Use external network named "traefik" + + # Nextcloud service + nextcloud: + image: nextcloud:latest + restart: always + hostname: nextcloud # Set hostname for Nextcloud container + environment: + VIRTUAL_HOST: ${NEXTCLOUD_HOST} # Set virtual host for Nextcloud + MYSQL_HOST: mysql-nextcloud # Set MySQL host for Nextcloud + MYSQL_DATABASE: ${NEXTCLOUD_DB_NAME} # Set Nextcloud database name + MYSQL_USER: ${NEXTCLOUD_DB_USER} # Set Nextcloud database user + MYSQL_PASSWORD: ${NEXTCLOUD_DB_PASSWORD} # Set Nextcloud database password + NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER} # Set Nextcloud admin user + NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD} # Set Nextcloud admin password + NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_HOST} # Set trusted domains for Nextcloud + volumes: + - /mnt/storage/nextcloud/data:/var/www/html # Mount Nextcloud data directory + - /mnt/storage/nextcloud/config:/var/www/html/config # Mount Nextcloud config directory + labels: + - "traefik.enable=true" # Enable Traefik for this service + - "traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_HOST}`)" # Route Nextcloud to specified host + - "traefik.http.routers.nextcloud.entrypoints=websecure" # Use HTTPS entrypoint for Nextcloud + - "traefik.http.routers.nextcloud.tls=true" # Enable TLS for Nextcloud + - "traefik.http.services.ghost.loadbalancer.server.port=80" # Set load balancer port for Nextcloud + - "traefik.http.routers.nextcloud.tls.certresolver=myresolver" # Use Let's Encrypt resolver for Nextcloud + - "traefik.http.routers.nextcloud.middlewares=nc-rep,nc-header" # Use redirect and header middlewares for Nextcloud + - "traefik.http.middlewares.nc-rep.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav" # Set regex for redirect middleware + - "traefik.http.middlewares.nc-rep.redirectregex.replacement=https://$$1/remote.php/dav/" # Set replacement for redirect middleware + - "traefik.http.middlewares.nc-rep.redirectregex.permanent=true" # Set redirect as permanent + - "traefik.http.middlewares.nc-header.headers.frameDeny=true" # Set header for frame deny + - "traefik.http.middlewares.nc-header.headers.sslRedirect=true" # Set header for SSL redirect + - "traefik.http.middlewares.nc-header.headers.contentTypeNosniff=true" # Set header for content type nosniff + - "traefik.http.middlewares.nc-header.headers.stsIncludeSubdomains=true" # Set header for STS include subdomains + - "traefik.http.middlewares.nc-header.headers.stsPreload=true" # Set header for STS preload + - "traefik.http.middlewares.nc-header.headers.stsSeconds=31536000" # Set header for STS seconds + - "traefik.http.middlewares.nc-header.headers.referrerPolicy=same-origin" # Set header for referrer policy + - "traefik.http.middlewares.nc-header.headers.browserXssFilter=true" # Set header for browser XSS filter + - "traefik.http.middlewares.nc-header.headers.customRequestHeaders.X-Forwarded-Proto=https" # Set custom request header for X-Forwarded-Proto + - "traefik.http.middlewares.nc-header.headers.customRequestHeaders.X-Forwarded-Proto=websecure" # Set custom request header for X-Forwarded-Proto + - "traefik.http.middlewares.nc-header.headers.customResponseHeaders.X-Robots-Tag=none" # Set custom response header for X-Robots-Tag + - "traefik.http.middlewares.nc-header.headers.customFrameOptionsValue=SAMEORIGIN" # Set custom frame options value + networks: + - traefik # Use external network named "traefik" + + # MySQL service for Ghost + mysql-ghost: + image: mysql:latest + restart: always + environment: + MYSQL_ROOT_PASSWORD: ${GHOST_DB_ROOT_PASSWORD} # Set MySQL root password + MYSQL_DATABASE: ${GHOST_DB_NAME} # Set Ghost database name + MYSQL_USER: ${GHOST_DB_USER} # Set Ghost database user + MYSQL_PASSWORD: ${GHOST_DB_PASSWORD} # Set Ghost database password + volumes: + - /mnt/storage/mysql-ghost:/var/lib/mysql # Mount MySQL data directory + hostname: mysql-ghost # Set hostname for MySQL container + networks: + - traefik # Use external network named "traefik" + + # Ghost service + ghost: + image: ghost:latest + restart: always + environment: + url: ${GHOST_URL} # Set Ghost URL + database__client: mysql # Set Ghost database client + database__connection__host: mysql-ghost # Set MySQL host for Ghost + database__connection__user: ${GHOST_DB_USER} # Set Ghost database user + database__connection__password: ${GHOST_DB_PASSWORD} # Set Ghost database password + database__connection__database: ${GHOST_DB_NAME} # Set Ghost database name + volumes: + - /mnt/storage/ghost/content:/var/lib/ghost/content # Mount Ghost content directory + labels: + - "traefik.enable=true" # Enable Traefik for this service + - "traefik.http.routers.ghost.rule=Host(`${GHOST_DOMAIN}`)" # Route Ghost to specified host + - "traefik.http.routers.ghost.entrypoints=websecure" # Use HTTPS entrypoint for Ghost + - "traefik.http.routers.ghost.tls=true" # Enable TLS for Ghost + - "traefik.http.routers.ghost.tls.certresolver=myresolver" # Use Let's Encrypt resolver for Ghost + - "traefik.http.services.ghost.loadbalancer.server.port=2368" # Set load balancer port for Ghost + - "traefik.http.routers.ghost.middlewares=redirect-to-https@docker" # Use redirect middleware for Ghost + networks: + - traefik # Use external network named "traefik" + + +networks: + traefik: + external: true # Use external network named "traefik" + +# version: '3' + +# services: +# traefik: +# image: traefik:v2.4 +# command: +# - "--api.insecure=true" +# - "--providers.docker=true" +# - "--providers.docker.exposedbydefault=false" +# - "--entrypoints.web.address=:80" +# - "--entrypoints.websecure.address=:443" +# - "--certificatesresolvers.myresolver.acme.email=${ACME_EMAIL}" +# - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" +# - "--certificatesresolvers.myresolver.acme.httpchallenge=true" +# - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" +# ports: +# - "80:80" +# - "443:443" +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock:ro +# - /mnt/storage/hndrx.co/traefik/letsencrypt:/letsencrypt +# labels: +# - "traefik.enable=true" +# - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" +# - "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_HOST}`)" +# - "traefik.http.routers.traefik.entrypoints=websecure" +# - "traefik.http.routers.traefik.tls=true" +# - "traefik.http.routers.traefik.tls.certresolver=myresolver" +# - "traefik.http.routers.traefik.service=api@internal" +# - "traefik.http.routers.traefik.middlewares=redirect-to-https@docker" +# networks: +# - traefik + +# mysql-nextcloud: +# image: mysql:latest +# restart: always +# environment: +# MYSQL_DATABASE: ${NEXTCLOUD_DB_NAME} +# MYSQL_USER: ${NEXTCLOUD_DB_USER} +# MYSQL_ROOT_PASSWORD: ${NEXTCLOUD_DB_ROOT_PASSWORD} +# MYSQL_PASSWORD: ${NEXTCLOUD_DB_PASSWORD} +# hostname: mysql-nextcloud +# volumes: +# - /mnt/storage/mysql-nextcloud:/var/lib/mysql +# networks: +# - traefik + +# nextcloud: +# image: nextcloud:latest +# restart: always +# hostname: nextcloud +# environment: +# VIRTUAL_HOST: ${NEXTCLOUD_HOST} +# MYSQL_HOST: mysql-nextcloud +# MYSQL_DATABASE: ${NEXTCLOUD_DB_NAME} +# MYSQL_USER: ${NEXTCLOUD_DB_USER} +# MYSQL_PASSWORD: ${NEXTCLOUD_DB_PASSWORD} +# NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER} +# NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD} +# NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_HOST} +# volumes: +# - /mnt/storage/nextcloud/data:/var/www/html +# - /mnt/storage/nextcloud/config:/var/www/html/config +# labels: +# - "traefik.enable=true" +# - "traefik.http.routers.nextcloud.rule=Host(`${NEXTCLOUD_HOST}`)" +# - "traefik.http.routers.nextcloud.entrypoints=websecure" +# - "traefik.http.routers.nextcloud.tls=true" +# - "traefik.http.services.ghost.loadbalancer.server.port=80" +# - "traefik.http.routers.nextcloud.tls.certresolver=myresolver" +# - "traefik.http.routers.nextcloud.middlewares=nc-rep,nc-header" +# - "traefik.http.middlewares.nc-rep.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav" +# - "traefik.http.middlewares.nc-rep.redirectregex.replacement=https://$$1/remote.php/dav/" +# - "traefik.http.middlewares.nc-rep.redirectregex.permanent=true" +# - "traefik.http.middlewares.nc-header.headers.frameDeny=true" +# - "traefik.http.middlewares.nc-header.headers.sslRedirect=true" +# - "traefik.http.middlewares.nc-header.headers.contentTypeNosniff=true" +# - "traefik.http.middlewares.nc-header.headers.stsIncludeSubdomains=true" +# - "traefik.http.middlewares.nc-header.headers.stsPreload=true" +# - "traefik.http.middlewares.nc-header.headers.stsSeconds=31536000" +# - "traefik.http.middlewares.nc-header.headers.referrerPolicy=same-origin" +# - "traefik.http.middlewares.nc-header.headers.browserXssFilter=true" +# - "traefik.http.middlewares.nc-header.headers.customRequestHeaders.X-Forwarded-Proto=https" +# - "traefik.http.middlewares.nc-header.headers.customRequestHeaders.X-Forwarded-Proto=websecure" +# - "traefik.http.middlewares.nc-header.headers.customResponseHeaders.X-Robots-Tag=none" +# - "traefik.http.middlewares.nc-header.headers.customFrameOptionsValue=SAMEORIGIN" +# networks: +# - traefik + +# mysql-ghost: +# image: mysql:latest +# restart: always +# environment: +# MYSQL_ROOT_PASSWORD: ${GHOST_DB_ROOT_PASSWORD} +# MYSQL_DATABASE: ${GHOST_DB_NAME} +# MYSQL_USER: ${GHOST_DB_USER} +# MYSQL_PASSWORD: ${GHOST_DB_PASSWORD} +# volumes: +# - /mnt/storage/mysql-ghost:/var/lib/mysql +# hostname: mysql-ghost +# networks: +# - traefik + +# ghost: +# image: ghost:latest +# restart: always +# environment: +# url: ${GHOST_URL} +# database__client: mysql +# database__connection__host: mysql-ghost +# database__connection__user: ${GHOST_DB_USER} +# database__connection__password: ${GHOST_DB_PASSWORD} +# database__connection__database: ${GHOST_DB_NAME} +# volumes: +# - /mnt/storage/ghost/content:/var/lib/ghost/content +# labels: +# - "traefik.enable=true" +# - "traefik.http.routers.ghost.rule=Host(`${GHOST_DOMAIN}`)" +# - "traefik.http.routers.ghost.entrypoints=websecure" +# - "traefik.http.routers.ghost.tls=true" +# - "traefik.http.routers.ghost.tls.certresolver=myresolver" +# - "traefik.http.services.ghost.loadbalancer.server.port=2368" +# - "traefik.http.routers.ghost.middlewares=redirect-to-https@docker" +# networks: +# - traefik + + +# networks: +# traefik: +# external: true diff --git a/web-apps/docker-env.example b/web-apps/docker-env.example new file mode 100644 index 0000000..2898772 --- /dev/null +++ b/web-apps/docker-env.example @@ -0,0 +1,25 @@ + +# Traefik configuration +TRAEFIK_DOMAIN=example.com +TRAEFIK_CERT_RESOLVER=myresolver +TRAEFIK_HOST=example.com +ACME_EMAIL=admin@example.com + +# Nextcloud configuration +NEXTCLOUD_DOMAIN=cloud.example.com +NEXTCLOUD_ADMIN_USER=admin +NEXTCLOUD_ADMIN_PASSWORD=Password123! +NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com +NEXTCLOUD_DB_NAME=nextcloud_db +NEXTCLOUD_DB_USER=nextcloud_user +NEXTCLOUD_DB_ROOT_PASSWORD=nextcloud_mysql +NEXTCLOUD_DB_PASSWORD=nextcloud_mysql +NEXTCLOUD_HOST=cloud.example.com + +# Ghost configuration +GHOST_DOMAIN=blog.example.com +GHOST_DB_ROOT_PASSWORD=ghost_mysql +GHOST_DB_NAME=ghost_db +GHOST_DB_USER=ghost_user +GHOST_DB_PASSWORD=ghost_mysql +GHOST_URL=https://blog.example.com diff --git a/wordpress/docker-compose-wordpress.yaml b/wordpress/docker-compose-wordpress.yaml new file mode 100644 index 0000000..7705a50 --- /dev/null +++ b/wordpress/docker-compose-wordpress.yaml @@ -0,0 +1,39 @@ +version: '3' + +services: + mysql-wordpress: + image: mysql:latest + volumes: + - ${MYSQL_VOLUME}:/var/lib/mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + + wordpress: + depends_on: + - mysql-wordpress + image: wordpress:latest + restart: always + environment: + WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST} + WORDPRESS_DB_USER: ${WORDPRESS_DB_USER} + WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD} + WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME} + labels: + - "traefik.enable=true" + - "traefik.http.routers.wordpress.rule=Host(`${WORDPRESS_DOMAIN}`)" + - "traefik.http.routers.wordpress.entrypoints=websecure" + - "traefik.http.routers.wordpress.tls=true" + - "traefik.http.routers.wordpress.tls.certresolver=myresolver" + - "traefik.http.routers.wordpress.service=wordpress" + - "traefik.http.services.wordpress.loadbalancer.server.port=80" + volumes: + - ${WORDPRESS_VOLUME}:/var/www/html + +networks: + default: + external: + name: traefik diff --git a/wordpress/docker-wordpress-env.example b/wordpress/docker-wordpress-env.example new file mode 100644 index 0000000..6cf34b6 --- /dev/null +++ b/wordpress/docker-wordpress-env.example @@ -0,0 +1,15 @@ +MYSQL_ROOT_PASSWORD=mysqlrootpass +MYSQL_DATABASE=wordpress +MYSQL_USER=wordpress +MYSQL_PASSWORD=wordpress-password +WORDPRESS_DB_HOST=dbhostname +WORDPRESS_DB_USER=dbuser +WORDPRESS_DB_PASSWORD=dbPassword +WORDPRESS_DB_NAME=mysql-db-name +WORDPRESS_DOMAIN=your.example.com +WORDPRESS_ENTRYPOINT=websecure +WORDPRESS_PORT=80 +MYSQL_VOLUME=/path/to/mysql/storage +WORDPRESS_VOLUME=/path/to/wordpress/storage + +