{"id":20996173,"url":"https://github.com/stefan-kolb/docker-dojo","last_synced_at":"2025-10-10T17:05:15.140Z","repository":{"id":69208286,"uuid":"235962185","full_name":"stefan-kolb/docker-dojo","owner":"stefan-kolb","description":"Docker Workshop Coding Dojo","archived":false,"fork":false,"pushed_at":"2024-05-06T08:55:20.000Z","size":254,"stargazers_count":6,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-02T23:51:12.620Z","etag":null,"topics":["docker","docker-compose","dockerfile","microservices"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stefan-kolb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-24T08:04:40.000Z","updated_at":"2024-05-06T08:55:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"4079d844-88ec-4503-af12-31bae738574a","html_url":"https://github.com/stefan-kolb/docker-dojo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-kolb%2Fdocker-dojo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-kolb%2Fdocker-dojo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-kolb%2Fdocker-dojo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefan-kolb%2Fdocker-dojo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefan-kolb","download_url":"https://codeload.github.com/stefan-kolb/docker-dojo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254231078,"owners_count":22036294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","docker-compose","dockerfile","microservices"],"created_at":"2024-11-19T07:28:21.613Z","updated_at":"2025-10-10T17:05:10.092Z","avatar_url":"https://github.com/stefan-kolb.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docker Microservices Dojo\n\nIn this coding dojo, you will implement a mock-up of a web music player. We will leverage\nthe [Spotify API][1] and a [Java wrapper][2] to get access to music data. We will break down\nthe necessary functionality into a set of small microservices and orchestrate them to achieve the\ndesired use case. All services are implemented as RESTful Web Services and should be hosted inside\nseparate Docker containers. The following figure shows the overall architecture of the service\norchestration.\n\n```mermaid\nflowchart LR\nsubgraph docker-compose.yml\nW(Web UI)\nC(Charts)\nS(Search)\nI(Images)\nend\nSp((Spotify))\nW --\u003e C \u0026 S \u0026 I\nC \u0026 S \u0026 I -.- Sp\n```\n\n## Search\n\nThe Search service is the main service of the orchestration. It allows to query for artists or\nsong titles and returns the appropriate Spotify IDs on success. These IDs are the global identifiers\nthat can be passed to the other services to request an artist's top songs or cover images for a\nparticular track. The service exposes two different resources: one for tracks and one for\nartists. The necessary parameters can be passed via query params. For instance, the search resource\nfor tracks is available at `{hostaddress}/api/tracks/search?title={song title}\u0026artist={artist}`. The\ntrack search returns an object that contains the track ID, artist name, and song title.\nThe artist object solely returns the artist ID and the artist name.\n\n## Charts\n\nThe Charts service returns the current top songs for a particular artist.\nTo get a list of tracks (ID, title, artist) the endpoint needs a valid artist ID. The\nresource is exposed at `{hostaddress}/api/charts/{artistID}`.\n\n## Images\n\nThis service provides the cover art for a particular track ID. The endpoint is available at `{hostaddress}/api/covers/{trackID}`.\n\n## Web\n\nThe web project (written in Node.js) mimics a mock-up of a web music player and integrates all of the previously\nmentioned services. It will display the currently played song title and artist name together with\nthe cover art. Moreover, it will also show the current top songs of the artist.\nReplace the URLs with your service endpoints inside `routes/index.js` of the web project if necessary.\nThe user interface is available at `http://{docker-container-ip}:8080`.\nTo alter the currently played song, change the URL query params inside the browser\nwindow, e.g., `http://{docker-container-ip}/?title={songtitle}\u0026artist={artist name}`.\n\n## Task 1: Dockerize Services\n\nYour first task is to dockerize the services described above.\n\nTherefore, create a `Dockerfile` in the root folder of each of the services.\nFill the Dockerfile with the necessary steps to be able to create a Docker image and run a Docker container.\nVerify if the service is running correctly by calling an exposed endpoint with `curl` or your Browser.\nFor testing purposes, you can use artist ID `3XHO7cRUPCLOr6jwp8vsx5` and title ID `57tzAvfPHXHzCHUNp9AUBm`.\n\n### Web\n\nThe web project is based on Node.js. You might want to use a small Node.js base image like `node:13-alpine` for your Docker image.\nAs a first step, copy the artifacts of the web project into an appropriate folder of the image.\nAfterwards, you need to run `npm install` to pull the necessary dependencies of the app.\nFinally, the Node.js server can be started via `npm start`. Make sure you expose the appropriate server port from the container.\n\n### Search, Charts, Images\n\nThe charts, search, and images projects are all based on a Java Gradle build.\n\nAs Java code needs to be compiled, we need to use `gradle:6.0.1-jdk8` as base image.\nAs first step, copy the app artifacts into a folder inside the image.\nRun `gradle installDist` to create a runnable distribution at `build/install/{project_name}` including all dependencies of the Java application. You can get each of the project names from `settings.gradle`.\n\nTo run the application, you can execute the prepared shell startup scripts inside `build/install/{project_name}/bin/{project_name}`\n\nSlightly adapt the Dockerfiles for each of the remaining service projects.\nTo run and test the resulting services you need to call `docker run` with the `microservices.env` environment file.\n\n*Optionally*, we want to apply a [multi-stage build][3] here to avoid cluttering the final Docker image with the build artifacts (and keep the image size down) and only create a Docker image with the runnable artifacts. This is a great way to apply the builder pattern and avoid maintaining two separate Dockerfiles.\n\nTherefore, the application container can be based on `alpine`, where we simply install Java via `apk add -U openjdk8-jre`.\nNow, copy the compiled application artifacts `build/install/{project_name}` from the build stage inside the application container.\n\n\n## Task 2: Service Orchestration\n\nAll of the described services should be packaged inside their own Docker\ncontainer and orchestrated via Docker Compose.\nTherefore, adapt the existing `docker-compose.yml` in the root project folder.\nMake sure to set appropriate dependencies to allow an automatic bootstrapping of the service composition via `docker compose up`.\nThe services images, search, and charts need the `microservices.env` mounted as environment file that provides the credentials for the Spotify API.\n\nRemember, the user interface is available at `http://{docker-container-ip}:8080`. To alter the currently played song, change the URL query params inside the browser window, e.g., `http://{docker-container-ip}:8080/?title={songtitle}\u0026artist={artist name}`.\n\nAs an *optional* improvement, define separate named networks inside the Compose file that isolate at least the frontend from the backend services or even all of the services from each other.\n\n[1]: https://developer.spotify.com/web-api/\n[2]: https://github.com/thelinmichael/spotify-web-api-java\n[3]: https://docs.docker.com/develop/develop-images/multistage-build/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefan-kolb%2Fdocker-dojo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefan-kolb%2Fdocker-dojo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefan-kolb%2Fdocker-dojo/lists"}