Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Consul Cluster
|
||||
|
||||
|
||||
### Info:
|
||||
|
||||
This template creates 3 Consul nodes that uses RPC encryption with TLS and gossip encryption to secure connection between consul cluster nodes, configuration is generated with confd from Rancher metadata.
|
||||
|
||||
TLS is used to verify the authenticity of the servers and the clients using the verify_incoming and verify_outgoing options.
|
||||
|
||||
The variables used in this template include:
|
||||
|
||||
- Certificates and keys for Consul nodes.
|
||||
- CA certificate.
|
||||
- 16-bytes, Base64 encoded gossip encryption key.
|
||||
- Web UI option.
|
||||
- ACL options.
|
||||
|
||||
|
||||
The templates uses two Docker images one as the main image and the other one is the sidekick:
|
||||
|
||||
- consul.
|
||||
- [consul-config](https://github.com/galal-hussein/consul-config).
|
||||
|
||||
### Usage:
|
||||
|
||||
Select Consul from catalog.
|
||||
|
||||
Enter the certificates and keys for consul nodes, ca certificates, and the encryption key.
|
||||
|
||||
Click deploy.
|
||||
|
||||
The consul nodes will be bound to the Rancher managed network IPs.
|
||||
@@ -0,0 +1,41 @@
|
||||
consul-base:
|
||||
image: consul:0.8.1
|
||||
entrypoint:
|
||||
- /opt/rancher/bin/start_consul.sh
|
||||
net: "container:consul"
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
volumes_from:
|
||||
- consul-data
|
||||
consul-data:
|
||||
image: alpine:latest
|
||||
entrypoint:
|
||||
- /bin/true
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.container.start_once: true
|
||||
volumes:
|
||||
- /var/consul
|
||||
- /opt/rancher/bin
|
||||
- /opt/rancher/ssl
|
||||
- /opt/rancher/config
|
||||
net: none
|
||||
consul:
|
||||
image: husseingalal/consul-config:0.1.2
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.sidekicks: consul-base,consul-data
|
||||
volumes_from:
|
||||
- consul-data
|
||||
{{- if eq .Values.ui "true"}}
|
||||
consul-lb:
|
||||
ports:
|
||||
- 8500:8500/tcp
|
||||
expose:
|
||||
- 8500:8500/tcp
|
||||
tty: true
|
||||
image: rancher/load-balancer-service
|
||||
links:
|
||||
- consul:consul-base
|
||||
stdin_open: true
|
||||
{{- end }}
|
||||
@@ -0,0 +1,93 @@
|
||||
.catalog:
|
||||
name: "Consul"
|
||||
description: "Secure Consul cluster"
|
||||
version: "0.8-rancher1"
|
||||
upgrade_from: 0.0.0-rancher1
|
||||
uuid: consul-0
|
||||
questions:
|
||||
- variable: ca_crt
|
||||
label: "CA certificate"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul1_key
|
||||
label: "First consul key"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul1_crt
|
||||
label: "First consul certificate"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul2_key
|
||||
label: "Second consul key"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul2_crt
|
||||
label: "Second consul certificate"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul3_key
|
||||
label: "Third consul key"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: consul3_crt
|
||||
label: "Third consul certificate"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: gossip_key
|
||||
label: "Communication gossip key"
|
||||
type: "multiline"
|
||||
required: true
|
||||
- variable: enable_acl
|
||||
label: "ACL Access"
|
||||
type: "boolean"
|
||||
required: true
|
||||
default: false
|
||||
- variable: acl_default_policy
|
||||
label: "ACL Default Policy"
|
||||
type: "enum"
|
||||
options:
|
||||
- "allow"
|
||||
- "deny"
|
||||
default: "allow"
|
||||
required: true
|
||||
- variable: acl_down_policy
|
||||
label: "ACL Down Policy"
|
||||
type: "enum"
|
||||
options:
|
||||
- "allow"
|
||||
- "deny"
|
||||
default: "allow"
|
||||
required: true
|
||||
- variable: acl_master_token
|
||||
label: "ACL Master Token"
|
||||
type: "string"
|
||||
default: ""
|
||||
required: false
|
||||
- variable: ui
|
||||
label: "Enable UI"
|
||||
type: "boolean"
|
||||
default: false
|
||||
required: true
|
||||
consul:
|
||||
scale: 3
|
||||
metadata:
|
||||
ca.crt: |
|
||||
${ca_crt}
|
||||
consul1.crt: |
|
||||
${consul1_crt}
|
||||
consul1.key: |
|
||||
${consul1_key}
|
||||
consul2.crt: |
|
||||
${consul2_crt}
|
||||
consul2.key: |
|
||||
${consul2_key}
|
||||
consul3.crt: |
|
||||
${consul3_crt}
|
||||
consul3.key: |
|
||||
${consul3_key}
|
||||
enc.key: "${gossip_key}"
|
||||
acl.enabled: "${enable_acl}"
|
||||
acl.default_policy: "${acl_default_policy}"
|
||||
acl.down_policy: "${acl_down_policy}"
|
||||
acl.master_token: "${acl_master_token}"
|
||||
ui.enabled: ${ui}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Consul Cluster
|
||||
description: |
|
||||
Consul cluster
|
||||
version: 0.6-rancher1
|
||||
version: 0.8-rancher1
|
||||
category: Clustering
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Drone
|
||||
|
||||
### Info:
|
||||
|
||||
This template creates an instance of Drone CI server 0.5 along with selectable number of agents to perform the builds.
|
||||
|
||||
### Usage:
|
||||
|
||||
Select the Drone template from the catalog. Provide the following information:
|
||||
|
||||
1. Publish port
|
||||
2. Agents scale
|
||||
3. Drone secret
|
||||
4. Run mode. debug | release
|
||||
3. Remote driver and config. (Ie. GitHub)
|
||||
4. Database driver and config. (Ie. sqlite)
|
||||
|
||||
|
||||
See [Drone documentation](http://readme.drone.io/admin) for complete information.
|
||||
@@ -0,0 +1,79 @@
|
||||
version: '2'
|
||||
services:
|
||||
agent:
|
||||
image: drone/drone:0.5
|
||||
environment:
|
||||
DRONE_SERVER: ws://drone:8000/ws/broker
|
||||
DRONE_SECRET: ${drone_secret}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
links:
|
||||
- server:drone
|
||||
command:
|
||||
- agent
|
||||
labels:
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
server:
|
||||
image: drone/drone:0.5
|
||||
environment:
|
||||
GIN_MODE: ${gin_mode}
|
||||
DRONE_SECRET: ${drone_secret}
|
||||
DRONE_OPEN: ${drone_open}
|
||||
{{- if (.Values.drone_admin)}}
|
||||
DRONE_ADMIN: ${drone_admins}
|
||||
{{- end}}
|
||||
{{- if (.Values.drone_orgs)}}
|
||||
DRONE_ORGS: ${drone_orgs}
|
||||
{{- end}}
|
||||
{{- if eq .Values.drone_driver "github"}}
|
||||
DRONE_GITHUB: true
|
||||
DRONE_GITHUB_CLIENT: ${drone_driver_client}
|
||||
DRONE_GITHUB_SECRET: ${drone_driver_secret}
|
||||
{{- end}}
|
||||
{{- if eq .Values.drone_driver "bitbucket"}}
|
||||
DRONE_BITBUCKET: true
|
||||
DRONE_BITBUCKET_CLIENT: ${drone_driver_client}
|
||||
DRONE_BITBUCKET_SECRET: ${drone_driver_secret}
|
||||
{{- end}}
|
||||
{{- if eq .Values.drone_driver "gitlab"}}
|
||||
DRONE_GITLAB: true
|
||||
DRONE_GITLAB_CLIENT: ${drone_driver_secret}
|
||||
DRONE_GITLAB_SECRET: ${drone_driver_secret}
|
||||
DRONE_GITLAB_URL: ${drone_driver_url}
|
||||
{{- end}}
|
||||
{{- if eq .Values.drone_driver "gogs"}}
|
||||
DRONE_GOGS: true
|
||||
DRONE_GOGS_URL: ${drone_driver_url}
|
||||
{{- end}}
|
||||
{{- if ne .Values.database_driver "sqlite"}}
|
||||
DRONE_DATABASE_DRIVER: ${database_driver}
|
||||
DRONE_DATABASE_DATASOURCE: ${database_source}
|
||||
{{- end}}
|
||||
labels:
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
{{- if eq .Values.database_driver "sqlite"}}
|
||||
io.rancher.sidekicks: server-volume
|
||||
volumes_from:
|
||||
- server-volume
|
||||
server-volume:
|
||||
image: rawmind/alpine-volume:0.0.2-1
|
||||
environment:
|
||||
SERVICE_GID: '0'
|
||||
SERVICE_UID: '0'
|
||||
SERVICE_VOLUME: /var/lib/drone
|
||||
network_mode: none
|
||||
volumes:
|
||||
- /var/lib/drone
|
||||
labels:
|
||||
io.rancher.container.start_once: 'true'
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
{{- end}}
|
||||
lb:
|
||||
image: rancher/load-balancer-service
|
||||
ports:
|
||||
- ${host_port}:8000/tcp
|
||||
links:
|
||||
- server:server
|
||||
@@ -0,0 +1,123 @@
|
||||
version: 2
|
||||
catalog:
|
||||
name: Drone
|
||||
version: 0.5-rancher1
|
||||
upgrade_from: 0.5-rancher1
|
||||
description: |
|
||||
Drone CI Server ref http://readme.drone.io/admin/installation-guide/
|
||||
questions:
|
||||
- variable: host_port
|
||||
label: Drone server Host Port
|
||||
description: |
|
||||
Port that will be exposed on service creation
|
||||
required: true
|
||||
default: 8000
|
||||
type: int
|
||||
- variable: agent_scale
|
||||
label: Drone agent scale
|
||||
description: Drone agent scale to deploy
|
||||
required: true
|
||||
default: 1
|
||||
type: int
|
||||
- variable: drone_secret
|
||||
label: Server and agents sercret.
|
||||
description: Server and agents secret to be communicate. http://readme.drone.io/admin/user-registration/
|
||||
type: password
|
||||
required: true
|
||||
- variable: gin_mode
|
||||
label: Run mode
|
||||
description: "Drone run mode, GIN_MODE"
|
||||
type: enum
|
||||
default: "release"
|
||||
options:
|
||||
- "release"
|
||||
- "debug"
|
||||
required: true
|
||||
- variable: drone_open
|
||||
label: Open registration
|
||||
description: |
|
||||
Users self register. http://readme.drone.io/admin/user-registration/
|
||||
required: true
|
||||
default: true
|
||||
type: enum
|
||||
options:
|
||||
- true
|
||||
- false
|
||||
- variable: drone_admin
|
||||
label: Drone Admin
|
||||
description: List of admins for drone coma seperated. http://readme.drone.io/admin/user-admins/
|
||||
type: string
|
||||
required: false
|
||||
- variable: drone_orgs
|
||||
label: Organizations
|
||||
description: Comman seperated list of org that can access drone. http://readme.drone.io/admin/user-registration/
|
||||
type: string
|
||||
required: false
|
||||
- variable: "drone_driver"
|
||||
type: "enum"
|
||||
required: true
|
||||
label: "Remote Driver"
|
||||
default: "github"
|
||||
description: "Remote Git and Auth scheme. ref http://readme.drone.io/admin"
|
||||
options:
|
||||
- github
|
||||
- bitbucket
|
||||
- gitlab
|
||||
- gogs
|
||||
- variable: drone_driver_client
|
||||
label: Remote Driver client
|
||||
description: "Client key from remote driver. Required for github, bitbucket and gitlab."
|
||||
type: string
|
||||
required: false
|
||||
- variable: drone_driver_secret
|
||||
label: Remote Driver secret
|
||||
description: "Secret key from remote driver. Required for github, bitbucket and gitlab."
|
||||
type: string
|
||||
required: false
|
||||
- variable: drone_driver_url
|
||||
label: Remote Driver url
|
||||
description: "Remote Driver server url. Required for gitlab and gogs, http://readme.drone.io/admin"
|
||||
type: string
|
||||
required: false
|
||||
- variable: database_driver
|
||||
label: Database Driver
|
||||
description: "Database driver. If sqlite, additional volume would be mounted at /var/lib/drone."
|
||||
type: enum
|
||||
default: "sqlite"
|
||||
options:
|
||||
- "sqlite"
|
||||
- "mysql"
|
||||
- "postgres"
|
||||
required: true
|
||||
- variable: "database_source"
|
||||
type: "string"
|
||||
label: "Database source"
|
||||
description: "Database datasource. Required if database driver is mysql or postgres, http://readme.drone.io/admin/database-engines/"
|
||||
required: false
|
||||
services:
|
||||
agent:
|
||||
scale: ${agent_scale}
|
||||
start_on_create: true
|
||||
server:
|
||||
scale: 1
|
||||
start_on_create: true
|
||||
health_check:
|
||||
port: 8000
|
||||
interval: 2000
|
||||
unhealthy_threshold: 3
|
||||
strategy: recreate
|
||||
request_line: GET / HTTP/1.0
|
||||
healthy_threshold: 2
|
||||
response_timeout: 2000
|
||||
lb:
|
||||
scale: 1
|
||||
start_on_create: true
|
||||
load_balancer_config:
|
||||
haproxy_config: {}
|
||||
health_check:
|
||||
healthy_threshold: 2
|
||||
response_timeout: 2000
|
||||
port: 42
|
||||
unhealthy_threshold: 3
|
||||
interval: 2000
|
||||
strategy: recreate
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Drone
|
||||
description: |
|
||||
Drone CI Server
|
||||
version: 0.4-rancher2
|
||||
version: 0.5-rancher1
|
||||
category: Continuous Integration
|
||||
|
||||
@@ -5,7 +5,7 @@ services:
|
||||
tty: true
|
||||
image: webcenter/alpine-gocd-server:17.3.0-1
|
||||
volumes:
|
||||
{{- if (contains .Values.VOLUME_DRIVER_SERVER "/")}}
|
||||
{{- if eq (printf "%.1s" .Values.VOLUME_DRIVER_SERVER) "/" }}
|
||||
- ${VOLUME_DRIVER_SERVER}:/data
|
||||
{{- else}}
|
||||
- gocd-server-data:/data
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
- GOCD_PLUGIN_google-auth=https://github.com/gocd-contrib/gocd-oauth-login/releases/download/v2.3/google-oauth-login-2.3.jar
|
||||
- GOCD_PLUGIN_github-auth=https://github.com/gocd-contrib/gocd-oauth-login/releases/download/v2.3/github-oauth-login-2.3.jar
|
||||
{{- end}}
|
||||
{{- if (ne .Values.DEPLOY_LB "true") and .Values.PUBLISH_PORT}}
|
||||
{{- if and (ne .Values.DEPLOY_LB "true") (.Values.PUBLISH_PORT)}}
|
||||
ports:
|
||||
- ${PUBLISH_PORT}:8153
|
||||
{{- end}}
|
||||
@@ -46,7 +46,7 @@ services:
|
||||
{{- if eq .Values.DEPLOY_LB "true"}}
|
||||
lb:
|
||||
image: rancher/lb-service-haproxy:v0.6.2
|
||||
{{- if .Values.PUBLISH_PORT}}
|
||||
{{- if (.Values.PUBLISH_PORT)}}
|
||||
ports:
|
||||
- ${PUBLISH_PORT}:8153/tcp
|
||||
{{- else}}
|
||||
@@ -65,7 +65,7 @@ services:
|
||||
tty: true
|
||||
image: webcenter/alpine-gocd-agent:17.3.0-1
|
||||
volumes:
|
||||
{{- if (contains .Values.VOLUME_DRIVER_AGENT "/")}}
|
||||
{{- if eq (printf "%.1s" .Values.VOLUME_DRIVER_AGENT) "/"}}
|
||||
- ${VOLUME_DRIVER_AGENT}:/data
|
||||
{{- else}}
|
||||
- gocd-agent-data:/data
|
||||
@@ -102,7 +102,7 @@ services:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
image: index.docker.io/docker:1.13-dind
|
||||
volumes:
|
||||
{{- if (contains .Values.VOLUME_DRIVER_AGENT "/")}}
|
||||
{{- if eq (printf "%.1s" .Values.VOLUME_DRIVER_AGENT) "/"}}
|
||||
- ${VOLUME_DRIVER_AGENT}:/data
|
||||
{{- else}}
|
||||
- gocd-agent-data:/data
|
||||
@@ -114,12 +114,12 @@ volumes:
|
||||
gocd-scheduler-setting:
|
||||
driver: local
|
||||
per_container: true
|
||||
{{- if not (contains .Values.VOLUME_DRIVER_AGENT "/")}}
|
||||
{{- if ne (printf "%.1s" .Values.VOLUME_DRIVER_AGENT) "/"}}
|
||||
gocd-agent-data:
|
||||
driver: ${VOLUME_DRIVER_AGENT}
|
||||
per_container: true
|
||||
{{- end}}
|
||||
{{- if not (contains .Values.VOLUME_DRIVER_SERVER "/")}}
|
||||
{{- if ne (printf "%.1s" .Values.VOLUME_DRIVER_SERVER) "/"}}
|
||||
gocd-server-data:
|
||||
driver: ${VOLUME_DRIVER_SERVER}
|
||||
{{- end}}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Influxdb
|
||||
|
||||
### Info:
|
||||
|
||||
This template deploys a Influxdb.
|
||||
|
||||
|
||||
### Usage:
|
||||
|
||||
Select influxdb from catalog.
|
||||
|
||||
Change the following cloud9 default parameters, if you need:
|
||||
|
||||
- Expose influxdb=true # Exposed influxdb service
|
||||
- Influxdb port=8086 # Influxdb exposed port
|
||||
|
||||
Click deploy.
|
||||
|
||||
Influxdb can now be accessed over the Rancher network and over exposed port.
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
version: '2'
|
||||
services:
|
||||
{{- if eq .Values.EXPOSE_SERVICE "true"}}
|
||||
lb:
|
||||
image: rancher/lb-service-haproxy:v0.6.2
|
||||
ports:
|
||||
- ${influxdb_port}:8086/tcp
|
||||
labels:
|
||||
io.rancher.container.agent.role: environmentAdmin
|
||||
io.rancher.container.create_agent: 'true'
|
||||
{{- end}}
|
||||
influxdb:
|
||||
image: influxdb:1.2.2-alpine
|
||||
stdin_open: true
|
||||
tty: true
|
||||
labels:
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.sidekicks: influxdb-volume
|
||||
volumes_from:
|
||||
- influxdb-volume
|
||||
influxdb-volume:
|
||||
network_mode: "none"
|
||||
labels:
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.container.start_once: true
|
||||
environment:
|
||||
- SERVICE_UID=0
|
||||
- SERVICE_GID=0
|
||||
- SERVICE_VOLUME=/var/lib/influxdb
|
||||
volumes:
|
||||
- /var/lib/influxdb
|
||||
volume_driver: local
|
||||
image: rawmind/alpine-volume:0.0.2-1
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
.catalog:
|
||||
name: Influxdb
|
||||
description: |
|
||||
Influxdb
|
||||
version: 1.2.2-rancher1
|
||||
minimum_rancher_version: v1.0.0
|
||||
maintainer: "Raul Sanchez <rawmind@gmail.com>"
|
||||
uuid: influxdb-0
|
||||
questions:
|
||||
- variable: "EXPOSE_SERVICE"
|
||||
description: "Expose Influxdb"
|
||||
label: "Expose influxdb:"
|
||||
required: true
|
||||
type: enum
|
||||
default: "true"
|
||||
options:
|
||||
- "true"
|
||||
- "false"
|
||||
- variable: "influxdb_port"
|
||||
description: |
|
||||
Port to expose.
|
||||
label: "Influxdb port:"
|
||||
default: "8086"
|
||||
required: true
|
||||
type: "int"
|
||||
version: '2'
|
||||
services:
|
||||
lb:
|
||||
scale: 1
|
||||
start_on_create: true
|
||||
lb_config:
|
||||
certs: []
|
||||
port_rules:
|
||||
- hostname: ''
|
||||
priority: 1
|
||||
protocol: http
|
||||
service: influxdb
|
||||
source_port: ${influxdb_port}
|
||||
target_port: 8086
|
||||
health_check:
|
||||
response_timeout: 2000
|
||||
healthy_threshold: 2
|
||||
port: 42
|
||||
unhealthy_threshold: 3
|
||||
interval: 2000
|
||||
influxdb:
|
||||
scale: 1
|
||||
start_on_create: true
|
||||
health_check:
|
||||
response_timeout: 2000
|
||||
healthy_threshold: 2
|
||||
port: 8086
|
||||
unhealthy_threshold: 3
|
||||
interval: 2000
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 672 250" style="enable-background:new 0 0 672 250;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:url(#symbol_1_);}
|
||||
.st1{fill:url(#SVGID_1_);}
|
||||
.st2{fill:url(#SVGID_2_);}
|
||||
.st3{fill:url(#SVGID_3_);}
|
||||
.st4{fill:url(#SVGID_4_);}
|
||||
.st5{fill:url(#SVGID_5_);}
|
||||
.st6{fill:url(#SVGID_6_);}
|
||||
.st7{fill:url(#SVGID_7_);}
|
||||
</style>
|
||||
<g id="influxdb_logo">
|
||||
<linearGradient id="symbol_1_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="125" x2="483.0884" y2="125">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path id="symbol_2_" class="st0" d="M242.5,133.3l-7.6-33.2c-0.4-1.8-2.1-3.6-3.9-4.1l-34.9-10.7c-0.5-0.1-1-0.2-1.5-0.2
|
||||
c-1.5,0-3.1,0.6-4,1.5l-25,23.2c-1.3,1.2-2.1,3.6-1.7,5.4l8.1,35.5c0.4,1.8,2.1,3.6,3.9,4.1l32.6,10c0.5,0.1,1,0.2,1.5,0.2
|
||||
c1.5,0,3.1-0.6,4-1.5l26.7-24.8C242.2,137.5,242.9,135.1,242.5,133.3z M199.7,93.1l23.9,7.3c0.9,0.3,0.9,0.7,0,0.9l-12.6,2.9
|
||||
c-1,0.2-2.3-0.2-2.9-0.9l-8.8-9.5C198.6,93.2,198.8,92.9,199.7,93.1z M214.6,136c0.2,1-0.4,1.5-1.3,1.2l-25.8-7.9
|
||||
c-0.9-0.3-1.1-1.1-0.4-1.7l19.8-18.4c0.7-0.7,1.5-0.4,1.7,0.5L214.6,136z M172.1,112.6l21-19.5c0.7-0.7,1.8-0.6,2.5,0.1l10.5,11.3
|
||||
c0.7,0.7,0.6,1.8-0.1,2.5l-21,19.5c-0.7,0.7-1.8,0.6-2.5-0.1L172,115.1C171.4,114.4,171.4,113.3,172.1,112.6z M177.2,143.6
|
||||
l-5.6-24.3c-0.2-1,0.1-1.1,0.8-0.4l8.8,9.5c0.7,0.7,1,2.1,0.7,3l-3.8,12.3C177.9,144.5,177.4,144.5,177.2,143.6z M207.9,157.7
|
||||
l-27.3-8.4c-0.9-0.3-1.5-1.3-1.2-2.2l4.5-14.8c0.3-0.9,1.3-1.5,2.2-1.2l27.3,8.4c0.9,0.3,1.5,1.3,1.2,2.2l-4.5,14.8
|
||||
C209.8,157.5,208.8,158,207.9,157.7z M232.2,137.8l-18.3,17c-0.7,0.7-1.1,0.4-0.8-0.5l3.8-12.3c0.3-0.9,1.3-1.9,2.3-2.1l12.6-2.9
|
||||
C232.7,136.8,232.9,137.2,232.2,137.8z M234.2,134.2l-15.1,3.4c-1,0.2-1.9-0.4-2.1-1.3l-6.4-27.9c-0.2-1,0.4-1.9,1.3-2.1l15.1-3.4
|
||||
c1-0.2,1.9,0.4,2.1,1.3l6.4,27.9C235.7,133,235.1,134,234.2,134.2z"/>
|
||||
<g id="type_2_">
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="120.5383" x2="483.0884" y2="120.5383">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st1" d="M273.5,111.4l8.9-1.2l-6.3,35.8h-8.7L273.5,111.4z M276.1,96.3l8.9-1.2l-1.7,9.8l-8.9,1.3L276.1,96.3z"/>
|
||||
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="127.9909" x2="483.0884" y2="127.9909">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st2" d="M310.2,120.9c0.1-0.4,0.1-0.8,0.1-0.9c0-0.9-0.4-1.5-1.8-1.5c-2.3,0-7.2,2.2-10.5,4.1l-4.1,23.4h-8.7
|
||||
l6.1-34.5l7.5-1.3l-0.1,4.3c4.6-2.5,10.1-4.4,14.3-4.4c4.8,0,6.4,3.2,6.4,7c0,1.4-0.1,2.3-0.4,3.5l-4.5,25.5h-8.7L310.2,120.9z"
|
||||
/>
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="127.9185" x2="483.0884" y2="127.9185">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st3" d="M347.4,117.8h-8.1l-5.3,29.8c-1,5.7-3.1,9.3-7.7,13.3l-5.6-5.2c2.8-2.7,4.1-5.1,4.7-8.9l5.1-29h-5.4l1.2-7.1
|
||||
h5.4l0.9-5.1c1.3-7.5,4.3-10.8,13.2-10.8c2.9,0,6.7,0.4,11.1,1.4l8.9-1.2l-9,50.9h-8.7l7.6-43.1c-3.5-0.7-7-1.1-9.8-1.1
|
||||
c-3,0-4.2,1-4.6,3.5l-0.9,5.4h8.8L347.4,117.8z"/>
|
||||
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="128.4249" x2="483.0884" y2="128.4249">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st4" d="M376.1,135.8c-0.1,0.5-0.1,0.8-0.1,0.9c0,0.9,0.4,1.5,1.8,1.5c2.3,0,7.2-2.2,10.5-4.1l4-22.8l8.9-1.2
|
||||
L395,146h-7.4l0.1-3.7c-4.6,2.5-10.1,4.4-14.3,4.4c-4.8,0-6.4-3.2-6.4-7c0-1.4,0.1-2.3,0.4-3.5l4.3-24.8l8.9-1.2L376.1,135.8z"/>
|
||||
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="128.0632" x2="483.0884" y2="128.0632">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st5" d="M414.9,128.2l-7.6-16.6l8.1-1.5l5.3,12.5l8.7-11.9h9.3l-14.4,18.6L432,146h-8.8l-4.8-10.2l-8.5,10.2h-9.3
|
||||
L414.9,128.2z"/>
|
||||
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="120.9" x2="483.0884" y2="120.9">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st6" d="M465.3,146h-7.4v-3.9c-3,2.7-6.8,4.6-12,4.6c-6.1,0-8.2-3.3-8.2-8c0-1.2,0.1-2.4,0.4-3.7l1.8-10.3
|
||||
c1.6-9,3.3-14.7,17.1-14.7c1.3,0,3.8,0.2,5.8,0.7l2.5-14.3l8.9-1.2L465.3,146z M461.6,117.8c-1.6-0.4-3.9-0.4-5.1-0.4
|
||||
c-5.6,0-7,2.2-7.8,6.9l-2.2,12.4c-0.1,0.4-0.1,0.7-0.1,0.9c0,1.3,0.9,1.9,2.5,1.9c3.7,0,8-3,9.8-5.3L461.6,117.8z"/>
|
||||
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="205.3238" y1="120.9" x2="483.0884" y2="120.9">
|
||||
<stop offset="0" style="stop-color:#4591ED"/>
|
||||
<stop offset="1" style="stop-color:#00C9FF"/>
|
||||
</linearGradient>
|
||||
<path class="st7" d="M483.1,96.3l8.9-1.2l-3.2,18c3.9-2.2,7.6-3.1,11.1-3.1c6.1,0,8.2,3.3,8.2,8c0,1.2-0.1,2.4-0.4,3.7L506,132
|
||||
c-1.9,10.6-5.5,14.7-18.2,14.7c-3.3,0-9.7-1.1-13.2-2.3L483.1,96.3z M484.2,138.9c1.6,0.3,3.3,0.5,5.1,0.5c5.6,0,7-2.3,7.8-6.9
|
||||
l2.2-12.4c0.1-0.4,0.1-0.7,0.1-0.9c0-1.3-0.9-1.9-2.5-1.9c-2.7,0-6.4,1.2-9.5,3.3L484.2,138.9z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
@@ -0,0 +1,7 @@
|
||||
name: Influxdb
|
||||
description: |
|
||||
Influxdb
|
||||
version: 1.2.2-rancher1
|
||||
category: Database
|
||||
maintainer: "Raul Sanchez <rawmind@gmail.com>"
|
||||
license:
|
||||
@@ -0,0 +1,33 @@
|
||||
kibana-vip:
|
||||
ports:
|
||||
- "${public_port}:80"
|
||||
restart: always
|
||||
tty: true
|
||||
image: rancher/load-balancer-service
|
||||
links:
|
||||
- nginx-proxy:kibana5
|
||||
stdin_open: true
|
||||
nginx-proxy-conf:
|
||||
image: rancher/nginx-conf:v0.2.0
|
||||
command: "-backend=rancher --prefix=/2015-07-25"
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
nginx-proxy:
|
||||
image: rancher/nginx:v1.9.4-3
|
||||
volumes_from:
|
||||
- nginx-proxy-conf
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.sidekicks: nginx-proxy-conf,kibana5
|
||||
external_links:
|
||||
- ${elasticsearch_source}:elasticsearch
|
||||
kibana5:
|
||||
restart: always
|
||||
tty: true
|
||||
image: kibana:5.3.0
|
||||
net: "container:nginx-proxy"
|
||||
stdin_open: true
|
||||
environment:
|
||||
ELASTICSEARCH_URL: "http://elasticsearch:9200"
|
||||
labels:
|
||||
io.rancher.container.hostname_override: container_name
|
||||
@@ -0,0 +1,24 @@
|
||||
.catalog:
|
||||
name: "Kibana"
|
||||
version: "5.3.0-rancher1"
|
||||
description: "Kibana: Explore & Visualize Your Data"
|
||||
questions:
|
||||
- variable: "elasticsearch_source"
|
||||
description: "Link to elasticsearch service or stack/service"
|
||||
label: "Elasticsearch source"
|
||||
type: "service"
|
||||
required: true
|
||||
default: "es/elasticsearch-clients"
|
||||
- variable: "public_port"
|
||||
label: "Public Port"
|
||||
description: "Unique public port for Kibana"
|
||||
type: "int"
|
||||
default: 80
|
||||
required: true
|
||||
|
||||
nginx-proxy:
|
||||
metadata:
|
||||
nginx:
|
||||
conf:
|
||||
servername: "kibana"
|
||||
upstream_port: 5601
|
||||
@@ -0,0 +1,79 @@
|
||||
# Traefik active load balancer (Experimental)
|
||||
|
||||
### Info:
|
||||
|
||||
This template deploys traefik active load balancers on top of Rancher. The configuration is generated and updated with confd from Rancher metadata.
|
||||
It would be deployed in hosts with label traefik_lb=true.
|
||||
|
||||
### Config:
|
||||
|
||||
- host_label = "traefik_lb=true" # Host label where to run traefik service.
|
||||
- http_port = 8080 # Port exposed to get access to the published services.
|
||||
- https_port = 8443 # Port exposed to get secured access to the published services.
|
||||
- admin_port = 8000 # Port exposed to get admin access to the traefik service.
|
||||
- https_enable = <false | true | only>
|
||||
- false: Enable http enpoints and disable https ones.
|
||||
- true: Enable http and https endpoints.
|
||||
- only: Enable https endpoints and redirect http to https.
|
||||
- acme_enable = false # Enable/Disable acme traefik support.
|
||||
- acme_email = "test@traefik.io" # acme user email
|
||||
- acme_ondemand = true # acme ondemand parameter.
|
||||
- acme_onhostrule = true # acme onHostRule parameter.
|
||||
- ssl_key # Paste your ssl key. *Required if you enable https
|
||||
- ssl_crt # Paste your ssl crt. *Required if you enable https
|
||||
- insecure_skip = false # Enable InsecureSkipVerify param.
|
||||
- refresh_interval = 10s # Interval to refresh traefik rules.toml from rancher-metadata.
|
||||
|
||||
NOTE: If you enable acme support, additional sidekick will be created for acme persistance.
|
||||
|
||||
### Service configuration labels:
|
||||
|
||||
Traefik labels has to be added in your services, in order to get included in traefik dynamic config.
|
||||
|
||||
- traefik.enable = <true | false>
|
||||
- true: the service will be published as *service_name.stack_name.traefik_domain*
|
||||
- stack: the service will be published as *stack_name.traefik_domain*. WARNING: You could have collisions inside services within your stack
|
||||
- false: the service will not be published
|
||||
- traefik.priority = <priority> # Override for frontend priority. 5 by default
|
||||
- traefik.protocol = < http | https > # Override the default http protocol
|
||||
- traefik.sticky = < true | false > # Enable/disable sticky sessions to the backend
|
||||
- traefik.alias = < alias > # Alternate names to route rule. Multiple values separated by ",". traefik.domain is appended. WARNING: You could have collisions BE CAREFULL
|
||||
- traefik.alias.fqdn = < alias fqdn > # Alternate names to route rule. Multiple values separated by ",". traefik.domain must be defined but is not appended here.
|
||||
- traefik.domain = < domain.name > # Domain names to route rules. Multiple domains separated by ","
|
||||
- traefik.domain.regexp = < domain.regexp > # Domain name regexp rule. Multiple domains separated by ","
|
||||
- traefik.port = < port > # Port to expose throught traefik
|
||||
- traefik.acme = < true | false > # Enable/disable ACME traefik feature
|
||||
- traefik.path = < path > # Path rule. Multiple values separated by ","
|
||||
- traefik.path.strip = < path > # Path strip rule. Multiple values separated by ","
|
||||
- traefik.path.prefix = < path > # Path prefix rule. Multiple values separated by ","
|
||||
- traefik.path.prefix.strip = < path > # Path prefix strip rule. Multiple values separated by ","
|
||||
|
||||
Details for configuring the traefik rules can be found at: https://docs.traefik.io/basics/#frontends
|
||||
|
||||
WARNING: Only services with healthy state are added to traefik, so health checks are mandatory.
|
||||
|
||||
### Usage:
|
||||
|
||||
Select Traefik from catalog.
|
||||
|
||||
Set the params.
|
||||
|
||||
Click deploy.
|
||||
|
||||
Services will be accessed throught hosts ip's whith $host_label:
|
||||
|
||||
- http://${service_name}.${stack_name}.${traefik.domain}:${http_port}
|
||||
- https://${service_name}.${stack_name}.${traefik.domain}:${https_port}
|
||||
|
||||
or
|
||||
|
||||
- http://${stack_name}.${traefik.domain}:${http_port}
|
||||
- https://${stack_name}.${traefik.domain}:${https_port}
|
||||
|
||||
If you set traefik.alias you service could also be acceses through
|
||||
|
||||
- http://${traefik.alias}.${traefik.domain}:${http_port}
|
||||
- https://${traefik.alias}.${traefik.domain}:${https_port}
|
||||
|
||||
Note: To access the services, you need to create A or CNAMES dns entries for every one.
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
traefik:
|
||||
ports:
|
||||
- ${admin_port}:8000/tcp
|
||||
- ${http_port}:${http_port}/tcp
|
||||
- ${https_port}:${https_port}/tcp
|
||||
log_driver: ''
|
||||
labels:
|
||||
io.rancher.scheduler.global: 'true'
|
||||
io.rancher.scheduler.affinity:host_label: ${host_label}
|
||||
io.rancher.scheduler.affinity:container_label_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.sidekicks: traefik-conf
|
||||
{{- if eq .Values.acme_enable "true" -}}
|
||||
,traefik-acme
|
||||
{{- end}}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
tty: true
|
||||
log_opt: {}
|
||||
image: rawmind/alpine-traefik:1.2.3-1
|
||||
environment:
|
||||
- CONF_INTERVAL=${refresh_interval}
|
||||
- TRAEFIK_HTTP_PORT=${http_port}
|
||||
- TRAEFIK_HTTPS_PORT=${https_port}
|
||||
- TRAEFIK_HTTPS_ENABLE=${https_enable}
|
||||
{{- if eq .Values.acme_enable "true"}}
|
||||
- TRAEFIK_ACME_ENABLE=${acme_enable}
|
||||
- TRAEFIK_ACME_EMAIL=${acme_email}
|
||||
- TRAEFIK_ACME_ONDEMAND=${acme_ondemand}
|
||||
- TRAEFIK_ACME_ONHOSTRULE=${acme_onhostrule}
|
||||
{{- end}}
|
||||
- TRAEFIK_INSECURE_SKIP=${insecure_skip}
|
||||
volumes_from:
|
||||
- traefik-conf
|
||||
{{- if eq .Values.acme_enable "true"}}
|
||||
- traefik-acme
|
||||
{{- end}}
|
||||
traefik-conf:
|
||||
log_driver: ''
|
||||
labels:
|
||||
io.rancher.scheduler.global: 'true'
|
||||
io.rancher.scheduler.affinity:host_label: ${host_label}
|
||||
io.rancher.scheduler.affinity:container_label_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.start_once: 'true'
|
||||
tty: true
|
||||
log_opt: {}
|
||||
image: rawmind/rancher-traefik:0.3.4-19
|
||||
net: none
|
||||
volumes:
|
||||
- /opt/tools
|
||||
{{- if eq .Values.acme_enable "true"}}
|
||||
traefik-acme:
|
||||
net: none
|
||||
labels:
|
||||
io.rancher.scheduler.affinity:container_label_soft_ne: io.rancher.stack_service.name=$${stack_name}/$${service_name}
|
||||
io.rancher.container.hostname_override: container_name
|
||||
io.rancher.container.start_once: true
|
||||
environment:
|
||||
- SERVICE_UID=10001
|
||||
- SERVICE_GID=10001
|
||||
- SERVICE_VOLUME=/opt/traefik/acme
|
||||
volumes:
|
||||
- /opt/traefik/acme
|
||||
volume_driver: ${VOLUME_DRIVER}
|
||||
image: rawmind/alpine-volume:0.0.2-1
|
||||
{{- end}}
|
||||
@@ -0,0 +1,107 @@
|
||||
.catalog:
|
||||
name: traefik
|
||||
version: v1.2.3-1-rancher1
|
||||
description: |
|
||||
(Experimental) Traefik load balancer.
|
||||
minimum_rancher_version: v0.59.0
|
||||
maintainer: "Raul Sanchez <rawmind@gmail.com>"
|
||||
uuid: traefik-0
|
||||
questions:
|
||||
- variable: "host_label"
|
||||
description: "Host label where to run traefik service."
|
||||
label: "Host label:"
|
||||
required: true
|
||||
default: "traefik_lb=true"
|
||||
type: "string"
|
||||
- variable: "http_port"
|
||||
description: "Traefik http public port to listen."
|
||||
label: "Http port:"
|
||||
required: true
|
||||
default: 8080
|
||||
type: "int"
|
||||
- variable: "https_port"
|
||||
description: "Traefik https public port to listen."
|
||||
label: "Https port:"
|
||||
required: true
|
||||
default: 8443
|
||||
type: "int"
|
||||
- variable: "admin_port"
|
||||
description: "Traefik admin public port to listen."
|
||||
label: "Admin port:"
|
||||
required: true
|
||||
default: 8000
|
||||
type: "int"
|
||||
- variable: "https_enable"
|
||||
label: "Enable HTTPS:"
|
||||
description: |
|
||||
Enable https working mode. If you activate, you need to fill SSL key and SSL crt in order to work.
|
||||
default: false
|
||||
required: true
|
||||
type: enum
|
||||
options:
|
||||
- false
|
||||
- true
|
||||
- only
|
||||
- variable: "acme_enable"
|
||||
description: "Enable acme support on traefik."
|
||||
label: "Enable ACME:"
|
||||
required: true
|
||||
default: false
|
||||
type: "boolean"
|
||||
- variable: "acme_email"
|
||||
description: "ACME user email."
|
||||
label: "ACME email:"
|
||||
required: true
|
||||
default: "test@traefik.io"
|
||||
type: "string"
|
||||
- variable: "acme_ondemand"
|
||||
description: "Enable acme ondemand."
|
||||
label: "ACME ondemand:"
|
||||
required: true
|
||||
default: true
|
||||
type: "boolean"
|
||||
- variable: "acme_onhostrule"
|
||||
description: "Enable acme onHostRule."
|
||||
label: "ACME onHostRule:"
|
||||
required: true
|
||||
default: true
|
||||
type: "boolean"
|
||||
- variable: "ssl_key"
|
||||
description: "SSL key to secure the service. *Required if you enable https"
|
||||
label: "SSL key"
|
||||
type: "multiline"
|
||||
required: false
|
||||
default: ""
|
||||
- variable: "ssl_crt"
|
||||
description: "SSL cert to secure the service. *Required if you enable https"
|
||||
label: "SSL crt"
|
||||
type: "multiline"
|
||||
required: false
|
||||
default: ""
|
||||
- variable: "insecure_skip"
|
||||
description: "Enable InsecureSkipVerify param."
|
||||
label: "InsecureSkipVerify:"
|
||||
required: true
|
||||
default: false
|
||||
type: "boolean"
|
||||
- variable: "refresh_interval"
|
||||
description: "Interval to poll/apply configuration changes."
|
||||
label: "Refresh Interval (s):"
|
||||
required: true
|
||||
default: 10
|
||||
type: "int"
|
||||
traefik:
|
||||
retain_ip: true
|
||||
health_check:
|
||||
port: 8000
|
||||
interval: 5000
|
||||
unhealthy_threshold: 3
|
||||
request_line: 'GET /dashboard/# HTTP/1.0'
|
||||
healthy_threshold: 2
|
||||
response_timeout: 5000
|
||||
metadata:
|
||||
traefik:
|
||||
ssl_key: |
|
||||
${ssl_key}
|
||||
ssl_crt: |
|
||||
${ssl_crt}
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Traefik
|
||||
description: |
|
||||
(Experimental) Traefik active load balancer
|
||||
version: v1.1.2-rancher1
|
||||
version: v1.2.3-1-rancher1
|
||||
category: Load Balancing
|
||||
maintainer: "Raul Sanchez <rawmind@gmail.com>"
|
||||
minimum_rancher_version: v0.59.0
|
||||
|
||||
@@ -3,7 +3,7 @@ version: '2'
|
||||
services:
|
||||
|
||||
elasticsearch:
|
||||
image: zammad/zammad-docker-compose:elasticsearch
|
||||
image: zammad/zammad-docker-compose:zammad-elasticsearch
|
||||
labels:
|
||||
io.rancher.container.pull_image: always
|
||||
restart: always
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
nginx:
|
||||
depends_on:
|
||||
- zammad
|
||||
image: zammad/zammad-docker-compose:nginx
|
||||
image: zammad/zammad-docker-compose:zammad-nginx
|
||||
labels:
|
||||
io.rancher.container.pull_image: always
|
||||
links:
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- data-zammad:/home/zammad
|
||||
|
||||
postgresql:
|
||||
image: zammad/zammad-docker-compose:postgresql
|
||||
image: zammad/zammad-docker-compose:zammad-postgresql
|
||||
labels:
|
||||
io.rancher.container.pull_image: always
|
||||
restart: always
|
||||
|
||||
Reference in New Issue
Block a user