Repository: rundeck/docker-zoo Branch: master Commit: 988cf357eeae Files: 56 Total size: 48.8 KB Directory structure: gitextract_sxdww34p/ ├── .gitignore ├── README.md ├── basic/ │ ├── README.md │ └── docker-compose.yml ├── cloud/ │ ├── .gitignore │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ └── nginx/ │ └── nginx.conf ├── config/ │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ └── remco/ │ ├── resources.d/ │ │ └── plugin-http-tours-framework.properties.toml │ └── templates/ │ └── plugin-http-tours-framework.properties ├── kubernetes/ │ ├── README.md │ ├── data/ │ │ └── admin-role.aclpolicy │ ├── minio-deployment.yaml │ ├── mysql-deployment.yaml │ ├── persistent-volumes.yaml │ └── rundeckpro-deployment.yaml ├── ldap/ │ ├── README.md │ ├── docker-compose.yml │ └── ldif/ │ └── 50-bootstrap.ldif ├── ldap-combined/ │ ├── README.md │ ├── docker-compose.yml │ └── ldif/ │ └── 50-bootstrap.ldif ├── ldap-combined-localroles/ │ ├── README.md │ ├── docker-compose.yml │ ├── ldif/ │ │ └── 50-bootstrap.ldif │ └── realm.properties ├── mysql/ │ ├── README.md │ └── docker-compose.yml ├── mysql8/ │ ├── README.md │ └── docker-compose.yml ├── oraclexe/ │ ├── README.md │ ├── docker-compose.yml │ └── lib/ │ └── .gitignore ├── percona-xtradb/ │ ├── Makefile │ ├── README.md │ ├── config/ │ │ └── cluster-cert.cnf │ └── docker-compose.yml ├── postgres/ │ ├── Dockerfile │ ├── README.md │ └── docker-compose.yml ├── runner/ │ ├── README.md │ └── docker-compose.yml ├── simple-cluster/ │ ├── README.md │ ├── docker-compose.yml │ ├── nginx.conf │ └── rundeck-node/ │ └── Dockerfile └── sqlserver/ ├── README.md ├── docker-compose.yml └── sqlserver/ ├── Dockerfile ├── entrypoint.sh ├── import-data.sh └── setup.sql ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .env oracle/lib/ojdbc8.jar .idea .DS_Store /percona-xtradb/certs/ ================================================ FILE: README.md ================================================ Rundeck Docker Zoo ================== Welcome to Rundeck's docker Zoo! Here we have many exhibits, both common _and_ exotic. These examples are great for trying out Rundeck in different setups, as well as a reference and starting place for your own deployments. ## Topics ### Authentication * [ldap](./ldap) * [ldap-combined](./ldap-combined) ### Extending Configuration * [config](./config) ### External Database Config * [mysql](./mysql) * [oraclexe](./oraclexe) * [postgres](./postgres) * [sqlserver](./sqlserver) ### Kubernetes * `Pro` [kubernetes](./kubernetes) ### Plugin Bundling * [cloud](./cloud) * [config](./config) ### Reverse Proxy * [cloud](./cloud) ### Runner * [runner](./runner) ## Conventions ### Config via `.env` Each docker-compose based exhibit has a `.env.dist` file that can be used to configure the example after being copied to `.env` . Some require it be populated and will call this out in the instructions. For all others it can be used to changed the Rundeck docker image and other various defaults. ### Rundeck Enterpise (fka Pro) images For each exhibit copy `.env.dist` to `.env` and uncomment the **pro** section. Provide the desired image and license file location: ```bash RUNDECK_IMAGE=rundeckpro/enterprise:SNAPSHOT RUNDECK_LICENSE_FILE=/path/to/rundeck-license.key ``` ### Updating/Changing Images For docker-compose without builds: ``` docker-compose down docker-compose pull ``` For docker-compose with builds: ``` docker-compose down docker-compose pull && docker-compose build --pull docker-compose up ``` ### Teardown To remove the setup including data volumes: ``` docker-compose down --volumes ``` ================================================ FILE: basic/README.md ================================================ Basic Exhibit ============= Quickest way to get up and running with a persistent data volume. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: basic/docker-compose.yml ================================================ version: '3' services: rundeck: image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} tty: true volumes: - data:/home/rundeck/server/data - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 volumes: data: ================================================ FILE: cloud/.gitignore ================================================ libext ================================================ FILE: cloud/Dockerfile ================================================ ARG RUNDECK_IMAGE FROM ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} COPY --chown=rundeck:root ./libext ./libext ================================================ FILE: cloud/README.md ================================================ Cloud Exhibit ============= This exhibit demonstrates what a typical cloud or multi-server deployment may look like. On display: * Running Rundeck behind a reverse proxy * Storage backend connected to a database server * Execution logs stored in S3 * Bundling extra plugins ### Reverse proxy This configuration exposes rundeck at `http://localhost:80` through nginx. A similiar setup is possible behind a cloud provider proxy, such as AWS ELB[v2], and the key is the `RUNDECK_SERVER_FORWARDED=true` environment variable which instructs Rundeck to respect the standard `X-Forwarded-*` headers. ## Setup **Fetch S3 log plugin** ``` mkdir libext cd libext wget https://github.com/rundeck-plugins/rundeck-s3-log-plugin/releases/download/v1.0.8/rundeck-s3-log-plugin-1.0.8.jar ``` **Populate `.env` file** ```bash cp .env.dist .env vim .env ``` **Build and Up** > **NOTE:** Building is not necessary the first time, however it will be to use newer or different images after the first build. ``` docker-compose build docker-compose up ``` ================================================ FILE: cloud/docker-compose.yml ================================================ version: '3' services: rundeck: build: context: ./ args: RUNDECK_IMAGE: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - mysql tty: true environment: RUNDECK_GRAILS_URL: http://localhost RUNDECK_SERVER_FORWARDED: 'true' RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://mysql/rundeck?autoReconnect=true&useSSL=false RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_NAME: org.rundeck.amazon-s3 RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_BUCKET: ${RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_BUCKET} RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_REGION: ${RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_REGION} RUNDECK_STORAGE_CONVERTER_1_CONFIG_PASSWORD: ${RUNDECK_STORAGE_PASSWORD} RUNDECK_CONFIG_STORAGE_CONVERTER_1_CONFIG_PASSWORD: ${RUNDECK_STORAGE_PASSWORD} volumes: - data:/home/rundeck/server/data - ${AWS_CREDENTIALS}:/home/rundeck/.aws/credentials - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key nginx: image: nginx links: - rundeck volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro ports: - 80:80 mysql: image: mysql:5.7 expose: - 3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck volumes: - dbdata:/var/lib/mysql volumes: data: dbdata: ================================================ FILE: cloud/nginx/nginx.conf ================================================ events { worker_connections 1024; } http { server { location / { proxy_pass http://rundeck:4440; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header User-Agent $http_user_agent; } } } ================================================ FILE: config/Dockerfile ================================================ ARG RUNDECK_IMAGE FROM ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} ADD --chown=rundeck:root https://github.com/rundeck-plugins/http-tours/releases/download/v0.1.0/http-tours-0.1.0.jar ./libext/ COPY --chown=rundeck:root remco /etc/remco ================================================ FILE: config/README.md ================================================ Configurations Exhibit ============= This exhibit demonstrates how to extend the configuration with settings not included in the base Rundeck docker images. On display: * Adding new configuration templates * Bundling plugins ### Configuration Extending the configuration involves adding new [Remco](https://github.com/HeavyHorst/remco) resources and templates. These are copied into the derived image and get combined into `framework.properties` and `rundeck-config.properties` during startup. Destinations: **framework.properties** ``` ${REMCO_TMP_DIR}/framework/ ``` **rundeck-config.properties** ``` ${REMCO_TMP_DIR}/rundeck-config/ ``` ## Setup **Build and Up** > **NOTE:** Building is not necessary the first time, however it will be to use newer or different images after the first build. ``` docker-compose build docker-compose up ``` ================================================ FILE: config/docker-compose.yml ================================================ version: '3' services: rundeck: build: context: ./ args: RUNDECK_IMAGE: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} environment: RUNDECK_TOUR_ENABLE: 'true' RUNDECK_TOUR_ENDPOINT: https://s3.amazonaws.com/tours.rundeck.com/prod tty: true volumes: - data:/home/rundeck/server/data - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 volumes: data: ================================================ FILE: config/remco/resources.d/plugin-http-tours-framework.properties.toml ================================================ [[template]] src = "${REMCO_TEMPLATE_DIR}/plugin-http-tours-framework.properties" dst = "${REMCO_TMP_DIR}/framework/plugin-http-tours-framework.properties" mode = "0644" ================================================ FILE: config/remco/templates/plugin-http-tours-framework.properties ================================================ {% if exists("/rundeck/tour/endpoint") %} framework.plugin.TourLoader.httptours.tourEndpoint={{ getv("/rundeck/tour/endpoint") }} framework.plugin.TourLoader.httptours.tourManifestName={{ getv("/rundeck/tour/manifest","tour-manifest.json") }} framework.plugin.TourLoader.httptours.toursSubpath={{ getv("/rundeck/tour/subpath","tours") }} {% endif %} ================================================ FILE: kubernetes/README.md ================================================ # Deploy Rundeck Enterprise on Kubernetes This example deploys a 2-node Rundeck Enterprise cluster with Mysql DB and Minio as logstorage. This is a workable architecture that can easily be used as a basis for deploying a fully HA production Rundeck cluster. ## Secrets and connectors Since this installation involves several services, they all need to be connected. So first we will create the encryption keys and user authentication information needed to tie this all together. ### Create Storage converter secret Create a master password for the storage converter - this encrypts Rundeck secrets as they get written to disk. You can refer to the documentation here: https://docs.rundeck.com/docs/administration/configuration/storage-facility.html#storage-converters ``` echo -n 'masterpassword123.' > ./masterpassword kubectl create secret generic rundeckpro-storage-converter --from-file=./masterpassword ``` ### Create Log Storage Access Credentials Create the AWS access key/secret to access the log storage (S3 or any similar storage based on S3, like minio) Note: you should probably create your own secrets values here. ``` echo -n 'minio' > ./awskey echo -n 'minio123' > ./awssecret kubectl create secret generic rundeckpro-log-storage --from-file=./awskey --from-file=./awssecret ``` ### Create Mysql database password ``` echo -n 'rundeck123.' > ./password kubectl create secret generic mysql-rundeckuser --from-file=./password ``` ### Create License Key Secret Add the Rundeck Enterprise license key as a Kubernetes secret. You will need a license key from your Rundeck account team for this step. Copy that license key into the data subdirectory of this path as ./data/rundeckpro-license.key ``` kubectl create secret generic rundeckpro-license --from-file=./data/rundeckpro-license.key ``` ### Add custom ACL from secrets By default, Rundeck manages ACL groups via a config file placed on the Rundeck instance. We'll store that config file as a Kubernetes secret, enabling us to keep it encrypted at rest as well as edit the ACLs later. To pick up the changes, delete the pods and let Kubernetes reschedule them. ``` kubectl create secret generic rundeckpro-admin-acl --from-file=./data/admin-role.aclpolicy ``` ## Deploy database and storage Rundeck Enterprise in a cluster configuration works better with common database and log storage. This step will stand up our underlying services for the Rundeck cluster. ``` kubectl apply -f persistent-volumes.yaml kubectl apply -f minio-deployment.yaml kubectl apply -f mysql-deployment.yaml ``` ## Deploy Rundeck ### Ingress Controller For this example, we are using Nginx as an ingress controller, which allows us to use the sticky sessions. Sticky sessions is required for clustered Rundeck. You will need to install it in order to make this example works (see https://github.com/kubernetes/ingress-nginx): On a local Docker Desktop environment: ``` kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml ``` * If you are running this in a cloud, bare-metal, or other environment, please refer to the documentation link and choose your provider specific setup for Nginx ingress .(see https://kubernetes.github.io/ingress-nginx/deploy/) After the Ingress is all setup, run the folling to wait until is ready to process requests: ``` kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=90s ``` ### Create Rundeckpro deployment The required Rundeck configuration options are already set in this file. Please read and review it to make sure it fits your intended purpose, or add to it if necessary. ``` kubectl apply -f rundeckpro-deployment.yaml ``` ### Access Rundeck WebUI You will need to port-forward the Rundeck service to access and interact with WebUI running in your Kubernetes cluster from your localhost. ``` kubectl port-forward service/rundeckpro 8080:8080 ``` ## Uninstall ``` kubectl delete deployment,service rundeckpro kubectl delete ingress rudeckpro-nginx kubectl delete deployment,service mysql kubectl delete deployment,service minio kubectl delete job minio-create-bucket ``` Note: These delete commands leave the persistent volumes and secrets in place so you can start up the environment again rather easily. ================================================ FILE: kubernetes/data/admin-role.aclpolicy ================================================ description: Admin, all access. context: project: '.*' # all projects for: resource: - allow: '*' # allow read/create all kinds adhoc: - allow: '*' # allow read/running/killing adhoc jobs job: - allow: '*' # allow read/write/delete/run/kill of all jobs node: - allow: '*' # allow read/run for all nodes by: group: ROLE_admin --- description: Admin, all access. context: application: 'rundeck' for: resource: - allow: '*' # allow create of projects project: - allow: '*' # allow view/admin of all projects project_acl: - allow: '*' # allow admin of all project-level ACL policies storage: - allow: '*' # allow read/create/update/delete for all /keys/* storage content by: group: ROLE_admin ================================================ FILE: kubernetes/minio-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: # This name uniquely identifies the Deployment name: minio-deployment labels: app: minio spec: strategy: type: Recreate selector: matchLabels: app: minio template: metadata: labels: # Label is used as selector in the service. app: minio spec: # Refer to the PVC created earlier volumes: - name: storage persistentVolumeClaim: # Name of the PVC created earlier claimName: minio-pv-claim containers: - name: minio # Pulls the default Minio image from Docker Hub image: minio/minio:latest args: - server - /data env: - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awskey - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awssecret ports: - containerPort: 9000 hostPort: 9000 # Mount the volume into the pod volumeMounts: - name: storage # must match the volume name, above mountPath: "/data" --- apiVersion: v1 kind: Service metadata: name: minio spec: type: LoadBalancer ports: - port: 9000 targetPort: 9000 protocol: TCP selector: app: minio --- # Create rundeck bucket apiVersion: batch/v1 kind: Job metadata: name: minio-create-bucket spec: completions: 1 template: metadata: name: minio-create-bucket spec: restartPolicy: Never containers: - name: minio-bucket image: minio/mc env: - name: MINIO_URL value: "http://minio.default.svc.cluster.local:9000" - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awskey - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awssecret - name: MINIO_BUCKET value: "rundeck" command: ["/bin/sh","-c","sleep 30 && mc config host add miniorundeck $MINIO_URL $MINIO_ACCESS_KEY $MINIO_SECRET_KEY && mc mb miniorundeck/$MINIO_BUCKET --ignore-existing"] ================================================ FILE: kubernetes/mysql-deployment.yaml ================================================ apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 targetPort: 3306 protocol: TCP selector: app: mysql type: LoadBalancer --- apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql spec: strategy: type: Recreate selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - image: mysql:5.7 args: - "--ignore-db-dir=lost+found" name: mysql env: # Use secret in real usage - name: "MYSQL_ROOT_PASSWORD" valueFrom: secretKeyRef: name: mysql-rundeckuser key: password - name: "MYSQL_DATABASE" value: rundeckdb - name: "MYSQL_USER" value: rundeck - name: "MYSQL_PASSWORD" valueFrom: secretKeyRef: name: mysql-rundeckuser key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim ================================================ FILE: kubernetes/persistent-volumes.yaml ================================================ kind: PersistentVolume apiVersion: v1 metadata: name: minio-pv spec: accessModes: - ReadWriteMany volumeMode: Filesystem persistentVolumeReclaimPolicy: Retain capacity: storage: 5Gi hostPath: path: /kubernetes/minio-data --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: minio-pv-claim spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi volumeName: minio-pv storageClassName: "" --- kind: PersistentVolume apiVersion: v1 metadata: name: mysql-pv spec: accessModes: - ReadWriteMany volumeMode: Filesystem persistentVolumeReclaimPolicy: Retain capacity: storage: 3Gi hostPath: path: /kubernetes/mysql-data --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mysql-pv-claim spec: accessModes: - ReadWriteMany resources: requests: storage: 3Gi volumeName: mysql-pv storageClassName: "" ================================================ FILE: kubernetes/rundeckpro-deployment.yaml ================================================ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: rundeckpro-nginx annotations: nginx.ingres.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "route" nginx.ingress.kubernetes.io/session-cookie-expires: "172800" nginx.ingress.kubernetes.io/session-cookie-max-age: "172800" spec: ingressClassName: nginx rules: - host: localhost http: paths: - path: / pathType: Prefix backend: service: name: rundeckpro port: number: 8080 --- apiVersion: v1 kind: Service metadata: name: rundeckpro spec: type: LoadBalancer ports: - protocol: TCP port: 8080 targetPort: 4440 selector: app: rundeckpro externalTrafficPolicy: Local sessionAffinity: ClientIP --- apiVersion: apps/v1 kind: Deployment metadata: name: rundeckpro namespace: default labels: app: rundeckpro spec: replicas: 1 selector: matchLabels: app: rundeckpro template: metadata: labels: app: rundeckpro spec: containers: - name: rundeck image: rundeckpro/enterprise:SNAPSHOT volumeMounts: - mountPath: /home/rundeck/etc/rundeckpro-license.key name: license subPath: rundeckpro-license.key - mountPath: /home/rundeck/etc/admin-role.aclpolicy name: acl subPath: admin-role.aclpolicy - mountPath: /home/rundeck/.kube/config name: kubeconfig subPath: config env: - name: RUNDECK_GRAILS_URL value: "http://localhost:8080" - name: RUNDECK_DATABASE_DRIVER value: "org.mariadb.jdbc.Driver" - name: RUNDECK_DATABASE_URL value: "jdbc:mysql://mysql.default.svc.cluster.local:3306/rundeckdb?autoReconnect=true&useSSL=false" - name: RUNDECK_DATABASE_USERNAME value: "rundeck" - name: RUNDECK_DATABASE_PASSWORD valueFrom: secretKeyRef: name: mysql-rundeckuser key: password - name: RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_NAME value: "com.rundeck.rundeckpro.amazon-s3" - name: RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_BUCKET value: "rundeck" - name: RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_REGION value: "us-east-2" - name: RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_ENDPOINT value: "http://minio.default.svc.cluster.local:9000" - name: RUNDECK_PLUGIN_EXECUTIONFILESTORAGE_S3_PATHSTYLE value: "true" - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awskey - name: AWS_SECRET_KEY valueFrom: secretKeyRef: name: rundeckpro-log-storage key: awssecret - name: RUNDECK_PLUGIN_CLUSTER_HEARTBEAT_CONSIDERDEAD value: "120" - name: RUNDECK_PLUGIN_CLUSTER_AUTOTAKEOVER_SLEEP value: "10" - name: RUNDECK_STORAGE_CONVERTER_1_CONFIG_PASSWORD valueFrom: secretKeyRef: name: rundeckpro-storage-converter key: masterpassword - name: RUNDECK_CONFIG_STORAGE_CONVERTER_1_CONFIG_PASSWORD valueFrom: secretKeyRef: name: rundeckpro-storage-converter key: masterpassword - name: RUNDECK_PLUGIN_CLUSTER_REMOTEEXECUTION_ENABLED value: "false" ports: - containerPort: 4440 livenessProbe: # an http probe httpGet: path: / port: 4440 scheme: HTTP initialDelaySeconds: 500 periodSeconds: 120 readinessProbe: httpGet: path: / port: 4440 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 5 volumes: - name: license secret: secretName: rundeckpro-license items: - key: rundeckpro-license.key path: rundeckpro-license.key - name: acl secret: secretName: rundeckpro-admin-acl items: - key: admin-role.aclpolicy path: admin-role.aclpolicy - name: kubeconfig secret: secretName: kubeconfig items: - key: config path: config ================================================ FILE: ldap/README.md ================================================ LDAP Exhibit ============= This setup configures Rundeck to authenticate users against LDAP. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: ldap/docker-compose.yml ================================================ version: '3' services: rundeck1: hostname: rundeck1 image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - ldap tty: true environment: RUNDECK_JAAS_MODULES_0: JettyCombinedLdapLoginModule RUNDECK_JAAS_LDAP_PROVIDERURL: ldap://ldap:389 RUNDECK_JAAS_LDAP_BINDDN: cn=admin,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_BINDPASSWORD: AdminPass123 RUNDECK_JAAS_LDAP_USERBASEDN: ou=users,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_ROLEBASEDN: ou=roles,dc=rdtest,dc=com volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 ldap: hostname: ldap image: osixia/openldap:1.2.1 environment: - LDAP_ORGANISATION=RD Test - LDAP_DOMAIN=rdtest.com - LDAP_ADMIN_PASSWORD=AdminPass123 volumes: - ./ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom:rw ports: - "389:389" command: --copy-service ================================================ FILE: ldap/ldif/50-bootstrap.ldif ================================================ # Define top-level entry: #dn: {{ LDAP_BASE_DN }} #objectClass: dcObject #objectClass: organization #o: Example, Inc. #dc: example # Define an entry to contain users: dn: ou=users,{{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: users # Define some users: dn: cn=admin, ou=users,{{ LDAP_BASE_DN }} uid: admin userPassword: admin objectClass: person objectClass: top objectClass: inetOrgPerson sn: The admin account for the Example client to use cn: admin dn: cn=build, ou=users,{{ LDAP_BASE_DN }} uid: build userPassword: {MD5}sNonVSCRjiPdYV4qdHUo8Q== ##### # MD5 creds, Base64 encoded #userPassword: build objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing builds only cn: build dn: cn=deploy, ou=users,{{ LDAP_BASE_DN }} uid: deploy userPassword: {CRYPT}de01JmlU8XXTQ ##### # CRYPT creds #userPassword: deploy objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing deployment only cn: deploy dn: cn=test, ou=users,{{ LDAP_BASE_DN }} uid: test userPassword: test objectClass: person objectClass: top objectClass: inetOrgPerson sn: Has no role access cn: test # Define an entry to contain roles: dn: ou=roles, {{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: roles # Define some roles and their membership: dn: cn=architect, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: architect dn: cn=admin, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: admin dn: cn=user, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: user dn: cn=build, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: build dn: cn=deploy, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} cn: deploy ================================================ FILE: ldap-combined/README.md ================================================ Combined JAAS Modules ===================== This configuration uses LDAP with a property file fall-back. The `build` user exists in LDAP, and the `admin` user is in the `realm.properties` file. **LDAP User:** `username: build` `password: build` **Property File User:** `username: admin` `password: admin` ================================================ FILE: ldap-combined/docker-compose.yml ================================================ version: '3' services: rundeck1: hostname: rundeck1 image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - ldap tty: true environment: RUNDECK_JAAS_MODULES_0: JettyCombinedLdapLoginModule RUNDECK_JAAS_LDAP_FLAG: sufficient RUNDECK_JAAS_LDAP_PROVIDERURL: ldap://ldap:389 RUNDECK_JAAS_LDAP_BINDDN: cn=admin,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_BINDPASSWORD: AdminPass123 RUNDECK_JAAS_LDAP_USERBASEDN: ou=users,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_ROLEBASEDN: ou=roles,dc=rdtest,dc=com RUNDECK_JAAS_MODULES_1: PropertyFileLoginModule RUNDECK_JAAS_FILE_FLAG: sufficient volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 ldap: hostname: ldap image: osixia/openldap:1.2.1 environment: - LDAP_ORGANISATION=RD Test - LDAP_DOMAIN=rdtest.com - LDAP_ADMIN_PASSWORD=AdminPass123 volumes: - ./ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom:rw ports: - "389:389" command: --copy-service ================================================ FILE: ldap-combined/ldif/50-bootstrap.ldif ================================================ # Define top-level entry: #dn: {{ LDAP_BASE_DN }} #objectClass: dcObject #objectClass: organization #o: Example, Inc. #dc: example # Define an entry to contain users: dn: ou=users,{{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: users # Define some users: dn: cn=build, ou=users,{{ LDAP_BASE_DN }} uid: build userPassword: {MD5}sNonVSCRjiPdYV4qdHUo8Q== ##### # MD5 creds, Base64 encoded #userPassword: build objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing builds only cn: build dn: cn=deploy, ou=users,{{ LDAP_BASE_DN }} uid: deploy userPassword: {CRYPT}de01JmlU8XXTQ ##### # CRYPT creds #userPassword: deploy objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing deployment only cn: deploy dn: cn=test, ou=users,{{ LDAP_BASE_DN }} uid: test userPassword: test objectClass: person objectClass: top objectClass: inetOrgPerson sn: Has no role access cn: test # Define an entry to contain roles: dn: ou=roles, {{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: roles # Define some roles and their membership: dn: cn=architect, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: architect dn: cn=admin, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: admin dn: cn=user, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: user dn: cn=build, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: build dn: cn=deploy, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} cn: deploy ================================================ FILE: ldap-combined-localroles/README.md ================================================ Using LDAP for authentication and local realm file for roles ===================== This configuration uses LDAP for authentication, and uses a realm property file for user roles. The user authentication is defined in LDAP, and the groups are defined in the realm.properties file. **LDAP Users:** * `username: build` `password: build` * `username: admin` `password: admin` ================================================ FILE: ldap-combined-localroles/docker-compose.yml ================================================ version: '3' services: rundeck1: hostname: rundeck1 image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - ldap tty: true environment: RUNDECK_GRAILS_URL: http://localhost:4440 RUNDECK_JAAS_MODULES_0: JettyCombinedLdapLoginModule RUNDECK_JAAS_LDAP_FLAG: requisite RUNDECK_JAAS_LDAP_PROVIDERURL: ldap://ldap:389 RUNDECK_JAAS_LDAP_BINDDN: cn=admin,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_BINDPASSWORD: AdminPass123 RUNDECK_JAAS_LDAP_USERBASEDN: ou=users,dc=rdtest,dc=com RUNDECK_JAAS_LDAP_IGNOREROLES: 'true' RUNDECK_JAAS_LDAP_STOREPASS: 'true' RUNDECK_JAAS_MODULES_1: JettyRolePropertyFileLoginModule RUNDECK_JAAS_FILE_FLAG: required RUNDECK_JAAS_FILE_USEFIRSTPASS: 'true' RUNDECK_JAAS_DEBUG: 'true' volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key - ./realm.properties:/home/rundeck/server/config/realm.properties ports: - 4440:4440 ldap: hostname: ldap image: osixia/openldap:1.2.1 environment: - LDAP_ORGANISATION=RD Test - LDAP_DOMAIN=rdtest.com - LDAP_ADMIN_PASSWORD=AdminPass123 volumes: - ./ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom:rw ports: - "389:389" command: --copy-service ================================================ FILE: ldap-combined-localroles/ldif/50-bootstrap.ldif ================================================ # Define top-level entry: #dn: {{ LDAP_BASE_DN }} #objectClass: dcObject #objectClass: organization #o: Example, Inc. #dc: example # Define an entry to contain users: dn: ou=users,{{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: users # Define some users: dn: cn=admin, ou=users,{{ LDAP_BASE_DN }} uid: admin userPassword: admin ##### # MD5 creds, Base64 encoded #userPassword: admin objectClass: person objectClass: top objectClass: inetOrgPerson sn: The admin account cn: admin dn: cn=build, ou=users,{{ LDAP_BASE_DN }} uid: build userPassword: {MD5}sNonVSCRjiPdYV4qdHUo8Q== ##### # MD5 creds, Base64 encoded #userPassword: build objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing builds only cn: build dn: cn=deploy, ou=users,{{ LDAP_BASE_DN }} uid: deploy userPassword: {CRYPT}de01JmlU8XXTQ ##### # CRYPT creds #userPassword: deploy objectClass: person objectClass: top objectClass: inetOrgPerson sn: The account to use to demonstrate managing deployment only cn: deploy dn: cn=test, ou=users,{{ LDAP_BASE_DN }} uid: test userPassword: test objectClass: person objectClass: top objectClass: inetOrgPerson sn: Has no role access cn: test # Define an entry to contain roles: dn: ou=roles, {{ LDAP_BASE_DN }} objectClass: organizationalUnit ou: roles # Define some roles and their membership: dn: cn=architect, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: architect dn: cn=admin, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} cn: admin dn: cn=user, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: user dn: cn=build, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=build,ou=users,{{ LDAP_BASE_DN }} cn: build dn: cn=deploy, ou=roles,{{ LDAP_BASE_DN }} objectClass: groupOfUniqueNames uniqueMember: cn=admin,ou=users,{{ LDAP_BASE_DN }} uniqueMember: cn=deploy,ou=users,{{ LDAP_BASE_DN }} cn: deploy ================================================ FILE: ldap-combined-localroles/realm.properties ================================================ admin:-,user,admin build:-,user ================================================ FILE: mysql/README.md ================================================ MySQL Exhibit ============= Demonstrates configuring Rundeck to use MySQL as an external database. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: mysql/docker-compose.yml ================================================ version: '3' services: rundeck: image: rundeck/rundeck:SNAPSHOT links: - mysql environment: RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://mysql/rundeck?autoReconnect=true&useSSL=false RUNDECK_GRAILS_URL: localhost:4440 volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 mysql: image: mysql:5.7 expose: - 3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck volumes: - dbdata:/var/lib/mysql volumes: dbdata: ================================================ FILE: mysql8/README.md ================================================ MySQL Exhibit ============= Demonstrates configuring Rundeck to use MySQL as an external database. # How to ## Startup Start the docker compose ``` docker-compose up ``` ## Teardown tear down and remove volumes ``` docker-compose down -v ``` ================================================ FILE: mysql8/docker-compose.yml ================================================ services: rundeck: image: rundeck/rundeck:SNAPSHOT links: - mysql environment: RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://mysql/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true RUNDECK_GRAILS_URL: http://localhost:4440 volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 mysql: image: mysql:8 expose: - 3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck volumes: - dbdata:/var/lib/mysql volumes: dbdata: ================================================ FILE: oraclexe/README.md ================================================ Oracle XE Exhibit ============== # How to Use ## Download Oracle JDBC Driver [Download the Oracle JDBC driver "ojdbc8.jar"](https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html) and place in `lib/` . ``` VERS=21.5.0.0 curl https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/$VERS/ojdbc8-$VERS.jar -o lib/ojdbc8-$VERS.jar ``` ## Start ``` docker-compose up -d ``` ## Stop ``` docker-compose down -v ``` ================================================ FILE: oraclexe/docker-compose.yml ================================================ version: '3' services: rundeck: image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - oracle environment: RUNDECK_GRAILS_URL: http://localhost:4440 RUNDECK_DATABASE_DRIVER: oracle.jdbc.OracleDriver RUNDECK_DATABASE_DIALECT: org.rundeck.hibernate.RundeckOracleDialect RUNDECK_DATABASE_USERNAME: system RUNDECK_DATABASE_PASSWORD: mypassword123 RUNDECK_DATABASE_URL: jdbc:oracle:thin:@oracle:1521:XE RUNDECK_DATABASE_VALIDATIONQUERY: SELECT 1 FROM DUAL volumes: - ./lib:/home/rundeck/server/lib - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 depends_on: - oracle oracle: image: container-registry.oracle.com/database/express:21.3.0-xe environment: ORACLE_PWD: mypassword123 expose: - 1521 ports: - 1521:1521 volumes: - dbdata:/opt/oracle/oradata volumes: dbdata: ================================================ FILE: oraclexe/lib/.gitignore ================================================ # Ignore everything in this directory * # Except this file !.gitignore ================================================ FILE: percona-xtradb/Makefile ================================================ RUNDECK_VERSION ?= 4.1.0 RUNDECK_IMAGE ?= rundeckpro/enterprise PERCONA_IMAGE ?= percona/percona-xtradb-cluster:8.0 default: bootstrap certs: mkdir -m 777 -p $(PWD)/certs docker run --name pxc-cert --rm -v $(PWD)/certs:/cert $(PERCONA_IMAGE) mysql_ssl_rsa_setup -d /cert bootstrap: certs docker compose up rddbnode1 -d echo "wait 35 seconds for main db to start..." && sleep 35 echo "Disabling cluster strict mode..." docker compose exec rddbnode1 mysql -hlocalhost -uroot -proot rundeck -e "SET GLOBAL pxc_strict_mode=PERMISSIVE;" docker compose run -i --rm rdbootstrap echo "wait 5 seconds before enforcing strict mode again" && sleep 5 docker compose exec rddbnode1 mysql -hlocalhost -uroot -proot rundeck -e "SET GLOBAL pxc_strict_mode=ENFORCING;" docker compose up rddbnode2 -d docker compose up rddbnode3 -d dbstart: docker compose up rddbnode1 rddbnode2 rddbnode3 -d start: docker compose up rundeck -d destroy: docker compose down -v rm -rf $(PWD)/certs .PHONY: default ================================================ FILE: percona-xtradb/README.md ================================================ Percona XtraDB Exhibit ======================= Demonstrates Rundeck + Simple Percona cluster setup ### Setup #### Create database certificates Generate the certificates used by the percona cluster nodes: ```shell $ make certs ``` A `certs`directory with the generated certs will be created. #### First-time Bootstrap of the DB cluster ***TIP**: `make bootstrap` will run this procedure automatically. This command will execute the following:* The first time you need to run the `rddbnode1` container first to bootstrap the cluster: ``` docker compose up rddbnode1 -d ``` - Log into the created mysql node and temporarily disable cluster checks. ```mysql mysql> SET GLOBAL pxc_strict_mode=PERMISSIVE; ``` Run the rundeck war in dbmigration mode so it creates the database schema: ```shell java -jar rundeck.war -m ``` Enable strict mode again on the database cluster. ```mysql mysql> SET GLOBAL pxc_strict_mode=ENFORCING; ``` Then start the other database nodes: ``` docker compose up rddbnode2 rddbnode3 -d ``` ### Startup Run `make start` or `docker-compose up rundeck -d` ### Teardown everything (including db) `make destroy` or `docker-compose down -v` ================================================ FILE: percona-xtradb/config/cluster-cert.cnf ================================================ [mysqld] ssl-ca = /cert/ca.pem ssl-cert = /cert/server-cert.pem ssl-key = /cert/server-key.pem [client] ssl-ca = /cert/ca.pem ssl-cert = /cert/client-cert.pem ssl-key = /cert/client-key.pem [sst] encrypt = 4 ssl-ca = /cert/ca.pem ssl-cert = /cert/server-cert.pem ssl-key = /cert/server-key.pem ================================================ FILE: percona-xtradb/docker-compose.yml ================================================ version: '3.9' services: rdbootstrap: image: ${RUNDECK_IMAGE:-rundeckpro/enterprise:SNAPSHOT} restart: "no" networks: - rundeck-network environment: RUNDECK_EXEC_CMD: java -jar rundeck.war -m RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://rddbnode1/rundeck?autoReconnect=true&useSSL=false rundeck: image: ${RUNDECK_IMAGE:-rundeckpro/enterprise:SNAPSHOT} networks: - rundeck-network environment: RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://rddbnode1/rundeck?autoReconnect=true&useSSL=false RUNDECK_GRAILS_URL: "http://localhost:4440" volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 rddbnode1: image: percona/percona-xtradb-cluster:8.0 networks: - rundeck-network ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck - CLUSTER_NAME=rundeck-cluster volumes: - ${PWD}/certs:/cert - ${PWD}/config:/etc/percona-xtradb-cluster.conf.d rddbnode2: image: percona/percona-xtradb-cluster:8.0 networks: - rundeck-network ports: - 3307:3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck - CLUSTER_NAME=rundeck-cluster - CLUSTER_JOIN=rddbnode1 volumes: - ${PWD}/certs:/cert - ${PWD}/config:/etc/percona-xtradb-cluster.conf.d rddbnode3: image: percona/percona-xtradb-cluster:8.0 networks: - rundeck-network ports: - 3308:3306 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=rundeck - MYSQL_USER=rundeck - MYSQL_PASSWORD=rundeck - CLUSTER_NAME=rundeck-cluster - CLUSTER_JOIN=rddbnode1 volumes: - ${PWD}/certs:/cert - ${PWD}/config:/etc/percona-xtradb-cluster.conf.d networks: rundeck-network: name: rundeck-network ================================================ FILE: postgres/Dockerfile ================================================ ARG RUNDECK_IMAGE FROM ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} COPY --chown=rundeck:root remco /etc/remco ================================================ FILE: postgres/README.md ================================================ PostgreSQL Exhibit ============= Demonstrates configuring Rundeck to use PostgreSQL as an external database. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: postgres/docker-compose.yml ================================================ version: '3' services: rundeck: image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - postgres environment: RUNDECK_DATABASE_DRIVER: org.postgresql.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:postgresql://postgres/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true RUNDECK_GRAILS_URL: http://localhost:4440 volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - 4440:4440 postgres: image: postgres expose: - 5432 environment: - POSTGRES_DB=rundeck - POSTGRES_USER=rundeck - POSTGRES_PASSWORD=rundeck volumes: - dbdata:/var/lib/postgresql/data volumes: dbdata: ================================================ FILE: runner/README.md ================================================ # Rundeck Runner Exhibit ## Configuration * `RUNNER_RUNDECK_SERVER_URL` - The base URL for your Rundeck Enterprise server. This could be `http://host.docker.internal:4440/` for local development or `https://your-subdomain.runbook.pagerduty.cloud/` for a Runbook Automation deployment. * `RUNNER_RUNDECK_CLIENT_ID` - The Runner id. * `RUNNER_RUNDECK_SERVER_TOKEN` - The Runner's secret token. ================================================ FILE: runner/docker-compose.yml ================================================ name: rundeck-runner services: runner: env_file: .env image: rundeckpro/runner:SNAPSHOT tty: true volumes: data: ================================================ FILE: simple-cluster/README.md ================================================ Simple Cluster Exhibit ============= Demonstrates configuring a Rundeck Enterprise Cluster, with NGinx as Load Balancer. ### Setup - Copy the provided `.env.dist` file as `.env`, and edit the values as needed providing the correct license file. - If you want to increase the cluster size, you'll need to adjust the `replicas` parameters in the `docker-compose.yml` file. And also adjust the `upstream` servers in the `nginx.conf` file. This in order to use nginx as actual load balancer instead of docker's default round-robin load balancer. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: simple-cluster/docker-compose.yml ================================================ # We fix the project name so DNS names are deterministic # This in order to use nginx LB in full, instead of docker's dns round-robin strategy. name: rundeck-cluster services: nginx: image: nginx depends_on: rundeck: condition: service_healthy volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro ports: - 80:80 # slim rundeck container to run database setup. # We do this first to prevent collisions between the two nodes when doing the first setup. rundeck-migration: image: ${RUNDECK_IMAGE:-rundeckpro/enterprise:SNAPSHOT} links: - dbase environment: RUNDECK_EXEC_CMD: "java -jar rundeck.war -m" RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://dbase/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true # main cluster rundeck: deploy: replicas: 2 # If this is changed, remember to adjust nginx configuration at nginx.conf image: rundeck-node build: context: rundeck-node args: RUNDECK_IMAGE: ${RUNDECK_IMAGE:-rundeckpro/enterprise:SNAPSHOT} links: - rundeck-migration - dbase depends_on: rundeck-migration: condition: service_completed_successfully environment: RUNDECK_GRAILS_URL: http://localhost RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver RUNDECK_DATABASE_USERNAME: rundeck RUNDECK_DATABASE_PASSWORD: rundeck RUNDECK_DATABASE_URL: jdbc:mysql://dbase/rundeck?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true RUNDECK_SECURITY_DBLOGIN_ENABLED: 'true' RUNDECK_SECURITY_DBLOGIN_CREATEADMINUSERANDROLES: 'true' RUNDECK_SECURITY_DBLOGIN_ADMINUSERNAME: admin RUNDECK_SECURITY_DBLOGIN_ADMINPASSWORD: admin RUNDECK_PLUGIN_CLUSTER_REMOTEEXECUTION_ENABLED: 'false' RUNDECK_FEATURE_ENTERPRISEACL_ENABLED: 'false' RUNDECK_FEATURE_ENTERPRISEACLTRANSFER_ENABLED: 'false' RUNDECK_SERVER_ADDRESS: 0.0.0.0 RUNDECK_GUI_STARTPAGE: jobs healthcheck: test: "curl -f http://localhost:4440" interval: 5s timeout: 10s retries: 50 start_period: 180s start_interval: 10s ports: - 4440 # expose: # - 4440 volumes: - logdata:/home/rundeck/var/logs:rw - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key dbase: image: mysql:8 ports: - 3306:3306 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: rundeck MYSQL_USER: rundeck MYSQL_PASSWORD: rundeck volumes: - dbdata_mysql:/var/lib/mysql volumes: logdata: dbdata_mysql: ================================================ FILE: simple-cluster/nginx.conf ================================================ events { worker_connections 1024; } http { upstream rundeck { ip_hash; server rundeck-cluster-rundeck-1:4440 max_fails=3 fail_timeout=30s; server rundeck-cluster-rundeck-2:4440 max_fails=3 fail_timeout=30s; } server { location / { proxy_pass http://rundeck; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_set_header X-Forwarded-Proto $scheme; #proxy_set_header User-Agent $http_user_agent; } } } ================================================ FILE: simple-cluster/rundeck-node/Dockerfile ================================================ ARG RUNDECK_IMAGE FROM ${RUNDECK_IMAGE} USER root #Create logs dir path RUN mkdir -p /home/rundeck/var/logs && \ chown rundeck:root /home/rundeck/var/logs # Set output log dir as volume so it can be shared across containers USER rundeck VOLUME /home/rundeck/var/logs ================================================ FILE: sqlserver/README.md ================================================ MSSQL Server Exhibit ============= Demonstrates configuring Rundeck to use MSSQL Server as an external database. ### Startup ``` docker-compose up ``` ### Teardown ``` docker-compose down -v ``` ================================================ FILE: sqlserver/docker-compose.yml ================================================ version: '3' services: rundeck: image: ${RUNDECK_IMAGE:-rundeck/rundeck:SNAPSHOT} links: - sqlserver environment: RUNDECK_GRAILS_URL: http://localhost:${RUNDECK_PORT:-4441} RUNDECK_DATABASE_DRIVER: com.microsoft.sqlserver.jdbc.SQLServerDriver RUNDECK_DATABASE_USERNAME: sa RUNDECK_DATABASE_PASSWORD: RundeckPassw0rd RUNDECK_DATABASE_URL: jdbc:sqlserver://sqlserver;DatabaseName=rundeck;autoReconnect=true;useSSL=false RUNDECK_DATABASE_DIALECT: org.hibernate.dialect.SQLServer2012Dialect volumes: - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key ports: - "${RUNDECK_PORT:-4441}:4440" depends_on: - sqlserver sqlserver: build: context: ./sqlserver expose: - 1433 ports: - 1433:1433 environment: - ACCEPT_EULA=Y - MSSQL_PID=Express - SA_PASSWORD=RundeckPassw0rd command: /bin/bash ./entrypoint.sh volumes: - mssql_data:/var/opt/mssql volumes: mssql_data: ================================================ FILE: sqlserver/sqlserver/Dockerfile ================================================ FROM mcr.microsoft.com/mssql/server:2022-latest USER root # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Bundle app source COPY . /usr/src/app # Grant permissions for the import-data script to be executable RUN chmod +x /usr/src/app/import-data.sh USER mssql CMD /bin/bash ./entrypoint.sh ================================================ FILE: sqlserver/sqlserver/entrypoint.sh ================================================ /opt/mssql/bin/sqlservr & /usr/src/app/import-data.sh && while true; do sleep 1; done ================================================ FILE: sqlserver/sqlserver/import-data.sh ================================================ #wait for the SQL Server to come up sleep 10s #run the setup script to create the DB and the schema in the DB /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P $SA_PASSWORD -d master -i setup.sql ================================================ FILE: sqlserver/sqlserver/setup.sql ================================================ CREATE DATABASE rundeck;