{"id":47589104,"url":"https://github.com/unicon/tier-grouper-deployment","last_synced_at":"2026-04-01T17:03:24.682Z","repository":{"id":54373643,"uuid":"128497721","full_name":"Unicon/tier-grouper-deployment","owner":"Unicon","description":"Contains materials related to the tutorial on running the TIER Grouper image on Docker Swarm","archived":false,"fork":false,"pushed_at":"2021-02-22T16:17:21.000Z","size":31,"stargazers_count":3,"open_issues_count":4,"forks_count":3,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-15T03:02:54.736Z","etag":null,"topics":["docker-swarm","grouper","grouper-database","kubernetes","secret","tier-grouper-image","tutorial"],"latest_commit_sha":null,"homepage":"https://www.youtube.com/watch?v=750J5UBTctw\u0026list=PLgUWExUT8bVcPHLnRe1yz4Cum_Avs6wQW","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Unicon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-07T04:58:09.000Z","updated_at":"2023-05-13T14:29:52.000Z","dependencies_parsed_at":"2022-08-13T13:41:00.482Z","dependency_job_id":null,"html_url":"https://github.com/Unicon/tier-grouper-deployment","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Unicon/tier-grouper-deployment","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unicon%2Ftier-grouper-deployment","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unicon%2Ftier-grouper-deployment/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unicon%2Ftier-grouper-deployment/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unicon%2Ftier-grouper-deployment/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Unicon","download_url":"https://codeload.github.com/Unicon/tier-grouper-deployment/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unicon%2Ftier-grouper-deployment/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-swarm","grouper","grouper-database","kubernetes","secret","tier-grouper-image","tutorial"],"created_at":"2026-04-01T17:03:11.679Z","updated_at":"2026-04-01T17:03:24.670Z","avatar_url":"https://github.com/Unicon.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deploying the TIER Grouper Image using Docker Swarm\n\nThis is the companion repository for the 4-part video tutorial that demonstrates how to deploy the TIER Grouper Docker image. In the video series, John Gasper, IAM Consultant, demonstrates:\n\n1. Create a simple Docker Swarm.\n1. Create an organizational base image.\n1. Populate the Grouper database.\n1. Create custom images for each component (vs a single common image).\n1. Create Docker Secrets and Docker Configs.\n1. Starting Swarm Services: Grouper Daemon, UI, and WS.\n1. Discussing next steps for moving forward in your deployment.\n\nThe videos are:\n\n1. Session 1: Grouper Environment Prep: https://youtu.be/750J5UBTctw\n1. Session 2: Grouper Database and Configs: https://youtu.be/agX-cm4-Okg\n1. Session 3: Grouper Services: https://youtu.be/HQ0qjOysexA\n1. Session 4: Grouper Continuing Forward: https://youtu.be/eMAL_RamYPc\n\n\u003e This tutorial was funded through Unicon's Grouper Open Source Support program. We thank our clients that are members of the program for their support that made this project possible. For more information about the Grouper OSS program, please see https://unicon.net/opensource/grouper.\n\n# Env Prep\n\n## Clean Centos 7 install\n\n- 4 processors \n- 4-6 gb RAM\n- 64 gb harddrive (we only use about 10gb)\n- all host/guest shared components turned off\n- user account that can sudo\n\n## On the new machine\n\n```\nip addr show\n```\n\n- SSH into the server (copy/paste, etc. is easier)\n- setup grouper.example.edu and idp.example.edu hostnames\n\n## VM Tools installed \n\n```\nsudo mount -t iso9660 /dev/sr0 /mnt\ncd /mnt\nsudo ./install\nsudo reboot\n```\n\n## Fully updated\n\n```\nsudo yum update\n```\n\n## Docker installed\n\n```\nsudo yum install -y yum-utils \\\n  device-mapper-persistent-data \\\n  lvm2\n\nsudo yum-config-manager \\\n    --add-repo https://download.docker.com/linux/centos/docker-ce.repo\n\nsudo yum install -y docker-ce \n\n#https://github.com/moby/moby/issues/16137#issuecomment-271615192\nsudo systemctl stop firewalld\nsudo systemctl disable firewalld\n\nsudo systemctl enable docker\nsudo systemctl start docker\n```\n\n## Install Git and pull project source\n\n```\nsudo yum install -y git\n\ngit clone https://github.com/Unicon/tier-grouper-deployment.git\ncd tier-grouper-deployment\n```\n\n\n# Installing Swarm\n\n```\nsudo docker swarm init\n```\n\n# Start Registry\n\n```\nsudo docker container run -d --name registry -p 5000:5000 registry:2\nsudo docker container ps\n```\n\n```\ncurl http://localhost:5000/v2/_catalog\n```\n\n# Ancillary Services\n\n## Start Database, LDAP, and Shibboleth IdP Services\n\n```\ncd ancillary\n\nsudo docker network create --driver overlay --scope swarm --attachable internal\nsudo docker stack deploy anc -c stack.yml\nsudo docker service ls\ncd ..\n```\n\n# Build Base Image\n\n```\ncd base\n\nsudo docker build --tag=localhost:5000/organization/grouper-base .\nsudo docker push localhost:5000/organization/grouper-base\n\ncd ..\n```\n\n## Populate Database\n\n```\nsudo docker container run -it --rm \\\n  --mount type=bind,src=$(pwd)/configs-and-secrets/grouper.hibernate.properties,dst=/run/secrets/grouper_grouper.hibernate.properties \\\n  --mount type=bind,src=$(pwd)/configs-and-secrets/subject.properties,dst=/run/secrets/grouper_subject.properties \\\n  --network internal \\\n  localhost:5000/organization/grouper-base gsh -registry -check -runscript -noprompt\n\nsudo docker container run -it --rm \\\n  --mount type=bind,src=$(pwd)/configs-and-secrets/grouper.hibernate.properties,dst=/run/secrets/grouper_grouper.hibernate.properties \\\n  --mount type=bind,src=$(pwd)/configs-and-secrets/subject.properties,dst=/run/secrets/grouper_subject.properties \\\n  --network internal \\\n  localhost:5000/organization/grouper-base gsh\n```\n\n```\ngrouperSession = GrouperSession.startRootSession();\naddMember(\"etc:sysadmingroup\",\"jgasper\");\n:quit\n```\n\n## Configs and Secrets\n\n```\ncd configs-and-secrets\n\nsudo docker secret create grouper.hibernate.properties grouper.hibernate.properties\nsudo docker secret create subject.properties subject.properties\nsudo docker secret create host-key.pem host-key.pem\nsudo docker config create shibboleth2.xml shibboleth2.xml\nsudo docker config create host-cert.pem host-cert.pem\n\ncd ..\n```\n\n\n\n\n\n# Create services\n\n## Daemon\n\n```\ncd daemon\n\nsudo docker build --tag=localhost:5000/organization/grouper-daemon .\nsudo docker push localhost:5000/organization/grouper-daemon\n\ncd ..\n```\n\n```\nsudo docker service create --detach --name=daemon \\\n  --network internal \\\n  --secret source=grouper.hibernate.properties,target=grouper_grouper.hibernate.properties \\\n  --secret source=subject.properties,target=grouper_subject.properties \\\n  localhost:5000/organization/grouper-daemon\n\nsudo docker service list\n```\n\n## UI\n\n```\ncd ui\n\nsudo docker build --tag=localhost:5000/organization/grouper-ui .\nsudo docker push localhost:5000/organization/grouper-ui\n\ncd ..\n```\n\n```\nsudo docker service create --detach --name=ui \\\n  --network internal \\\n  --publish 443:443 \\\n  --secret source=grouper.hibernate.properties,target=grouper_grouper.hibernate.properties \\\n  --secret source=subject.properties,target=grouper_subject.properties \\\n  --secret source=host-key.pem,target=host-key.pem \\\n  --config source=shibboleth2.xml,target=/etc/shibboleth/shibboleth2.xml \\\n  --config source=host-cert.pem,target=/etc/pki/tls/certs/host-cert.pem \\\n  --config source=host-cert.pem,target=/etc/pki/tls/certs/cachain.pem \\\n  localhost:5000/organization/grouper-ui\n  \nsudo docker service list\n```\n\n\u003chttps://\u003chostname_or_ip\u003e/grouper\u003e\n\n## WS\n\n```\ncd ws\n\nsudo docker build --tag=localhost:5000/organization/grouper-ws .\nsudo docker push localhost:5000/organization/grouper-ws\n\ncd ..\n```\n\n```\nsudo docker service create --detach --name=ws \\\n  --network internal \\\n  --publish 8443:443 \\\n  --secret source=grouper.hibernate.properties,target=grouper_grouper.hibernate.properties \\\n  --secret source=subject.properties,target=grouper_subject.properties \\\n  --secret host-key.pem \\\n  --config source=host-cert.pem,target=/etc/pki/tls/certs/host-cert.pem \\\n  --config source=host-cert.pem,target=/etc/pki/tls/certs/cachain.pem \\\n  localhost:5000/organization/grouper-ws\n\nsudo docker service list\n```\n\n\u003chttps://\u003chostname_or_ip\u003e:8443/grouper-ws/status?diagnosticType=db\u003e\n\n# Resetting the Env\n\n## Grouper Stuff\n\n```\nsudo docker service rm daemon\nsudo docker service rm ui\nsudo docker service rm ws\n\nsudo docker secret rm grouper.hibernate.properties\nsudo docker secret rm subject.properties\nsudo docker secret rm host-key.pem\nsudo docker config rm shibboleth2.xml\nsudo docker config rm host-cert.pem\n```\n\n## Everything else\n\n```\nsudo docker stack rm anc\nsudo docker container rm -f registry \nsudo docker network rm internal\n```\n\n# Bonus: Using a stack file to spin up the env\n\nDo you understand the `docker service` and `docker secret` subcommands? Try using the short-cut `stack.yml` file to save you some time.\n\n\u003e You still need to have the internal network defined, the DB populated, and an image registry started... along with a directory and idp (using the ancillary ones or external ones).\n\nStart up all the Grouper components and verify:\n\n```\nsudo docker stack deploy grouper -c stack.yml\nsudo docker stack ls\nsudo docker service ls\nsudo docker secret ls\n```\n\nShutdown the Grouper componenets and verify:\n\n```\nsudo docker stack rm grouper\nsudo docker stack ls\nsudo docker service ls\nsudo docker secret ls\n```\n\n\n# Bonus: Adding a new secret (or config) to an existing service\n\n```\nsudo docker service update daemon \\\n--secret-add source=grouper-loader.properties,target=grouper_grouper-loader.properties\nsudo docker service update ui \\\n--secret-add source=grouper-loader.properties,target=grouper_grouper-loader.properties\nsudo docker service update ws \\\n--secret-add source=grouper-loader.properties,target=grouper_grouper-loader.properties\n```\n\n# Bonus: Updating an Existing Secret\n\nLet's assuming we need to change the `grouper-loader.properties` secret. First we update the grouper-loader.properties file on the host with the desired changes. \n\n\u003e Note: `-2` is an arbitrary extension. If additional changes were being made the `--secret-rm` parameter would also need to be updated to include that last arbitrary extension. But the `target=grouper_grouper-loader.properties` remains the same.\n\n1. Add the new secret file:\n    ```\n    sudo docker secret create grouper-loader-2.properties grouper-loader.properties\n    ```\n\n1. Update the service removing the old secret and adding the new secret:\n    ```\n    sudo docker service update daemon \\\n    --secret-add source=grouper-loader-2.properties,target=grouper_grouper-loader.properties \\\n    --secret-rm grouper-loader.properties\n    sudo docker service update ui \\\n    --secret-add source=grouper-loader-2.properties,target=grouper_grouper-loader.properties \\\n    --secret-rm grouper-loader.properties\n    sudo docker service update ws \\\n    --secret-add source=grouper-loader-2.properties,target=grouper_grouper-loader.properties \\\n    --secret-rm grouper-loader.properties\n    ```\n\n1. At some point remove the old secret (this will prevent a `rollback` operation from working):\n    ```\n    sudo docker secret rm grouper-loader.properties\n    ```\n\n# Bonus: Rolling Back a Service Configuration Change\n\n```\nsudo docker service rollback daemon\nsudo docker service rollback ui\nsudo docker service rollback ws\n```\n\n# Bonus: Kubernetes Deployment Configuration\n\n1. Create the multi-part secret and configmaps:\n    ```\n    cd configs-and-secrets\n    kubectl create secret generic grouper --from-file=grouper.hibernate.properties --from-file=subject.properties --from-file=host-key.pem\n    kubectl create configmap shibboleth2.xml --from-file=shibboleth2.xml\n    kubectl create configmap host-certs --from-file=host-cert.pem --from-file=cachain.pem=host-cert.pem\n\n    cd..\n    ```\n    \n2. Apply the config    \n    ```\n    kubectl apply -f kubernetes.yaml\n    ```\n       \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funicon%2Ftier-grouper-deployment","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funicon%2Ftier-grouper-deployment","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funicon%2Ftier-grouper-deployment/lists"}