{"id":14155273,"url":"https://github.com/flemay/3musketeers","last_synced_at":"2026-04-17T08:10:54.746Z","repository":{"id":39982658,"uuid":"106680024","full_name":"flemay/3musketeers","owner":"flemay","description":"Test, build, and deploy your apps from anywhere, the same way!","archived":false,"fork":false,"pushed_at":"2026-02-20T12:46:32.000Z","size":5912,"stargazers_count":196,"open_issues_count":4,"forks_count":23,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-02-20T16:52:16.932Z","etag":null,"topics":["3musketeers","ci","cicd","cloudflare-pages","devcontainer","docker","docker-compose","documentation","github-actions","make","makefile","methodology","microservice","monolithic","pipelines","repeatability","typescript"],"latest_commit_sha":null,"homepage":"https://3musketeers.pages.dev","language":"MDX","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flemay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-10-12T10:44:09.000Z","updated_at":"2026-02-20T12:46:34.000Z","dependencies_parsed_at":"2025-12-12T17:06:55.370Z","dependency_job_id":null,"html_url":"https://github.com/flemay/3musketeers","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/flemay/3musketeers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flemay%2F3musketeers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flemay%2F3musketeers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flemay%2F3musketeers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flemay%2F3musketeers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flemay","download_url":"https://codeload.github.com/flemay/3musketeers/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flemay%2F3musketeers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31920591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["3musketeers","ci","cicd","cloudflare-pages","devcontainer","docker","docker-compose","documentation","github-actions","make","makefile","methodology","microservice","monolithic","pipelines","repeatability","typescript"],"created_at":"2024-08-17T08:02:37.413Z","updated_at":"2026-04-17T08:10:54.737Z","avatar_url":"https://github.com/flemay.png","language":"MDX","funding_links":[],"categories":["typescript","docker"],"sub_categories":[],"readme":"# 3 Musketeers\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"src/assets/logo/hero-v2.svg\" width=\"300\"\u003e\n\n**Test, build, and deploy your apps from anywhere, the same way!**\n\n[![Build Status][linkGitHubActionsProjectBadge]][linkGitHubActionsProject]\n[![License][linkLicenseBadge]][linkLicense]\n\n\u003c/div\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Overview](#overview)\n- [3 Musketeers website](#3-musketeers-website)\n  - [Prerequisites](#prerequisites)\n  - [Development](#development)\n  - [Deployment](#deployment)\n    - [0. Cloudflare account ID and API token](#0-cloudflare-account-id-and-api-token)\n    - [1. Envfile](#1-envfile)\n    - [2. Create](#2-create)\n    - [3. Deploy](#3-deploy)\n    - [4. Delete](#4-delete)\n  - [CI/CD](#cicd)\n  - [Visual elements](#visual-elements)\n- [Contributing](#contributing)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\u003c/details\u003e\n\n## Overview\n\n\u003c!-- Part of src/content/docs/about/what-is-3musketeers.md --\u003e\n\nThe 3 Musketeers is a pattern for developing software in a repeatable and\nconsistent manner. It leverages Make as an orchestration tool to test, build,\nrun, and deploy applications using Docker and Docker Compose. The Make and\nDocker/Compose commands for each application are maintained as part of the\napplication’s source code and are invoked in the same way whether run locally or\non a CI/CD server.\n\n\u003e [!NOTE]\n\u003e To learn more, please visit the [official website][link3Musketeers].\n\n## 3 Musketeers website\n\nThis repository is the [3 Musketeers website][link3Musketeers] built with\n[Astro Starlight][linkAstroStarlight]. This section explains how to develop,\ntest, and deploy using the 3 Musketeers methodology.\n\n### Prerequisites\n\n- [Docker](https://www.docker.com/)\n- [Compose](https://docs.docker.com/compose/)\n- [Make](https://www.gnu.org/software/make/)\n- [Cloudflare][linkCloudflarePages] account\n\n### Development\n\n```bash\n# Create a .env file\nmake envfile ENVFILE=env.example\n# Install dependencies\nmake deps copyDepsToHost\n\n# Format and check\nmake fmt check\n\n# Start Astro server for local development\nmake dev\n# Wait till the message 'dev-1  | 20:13:41 watching for file changes...' appears\n# Access the website in your browser at http://127.0.0.1:4321/\n# \\\u003cctrl-c\\\u003e to stop\n\n# Build static site\nmake build\n\n# Serve static site for local development\nmake previewDev\n# Access the website in your browser at http://127.0.0.1:4321/\n# \\\u003cctrl-c\\\u003e to stop\n\n# Serve static website in the background\nmake preview\n\n# Test static website\nmake testPreview\n\n# Clean\nmake clean\n```\n\n### Deployment\n\nThe 3 Musketeers website is deployed to [Cloudflare Pages][linkCloudflarePages].\nThis section shows how to create, deploy, and delete a Pages project using\n[Wrangler CLI][linkCloudflareWranglerCLI]. This is handy for previewing new\nchanges.\n\nGiven build, test and deployment are going to be done with GitHub Actions, this\nsection follows the [Direct Upload][linkCloudflareDirectUpload] and\n[Run Wrangler in CI/CD][linkCloudflareWranglerCICD] directives.\n\n\u003e [!NOTE]\n\u003e This section requires the static site to be have been generated with\n\u003e `make build`\n\n#### 0. Cloudflare account ID and API token\n\nTo interact with Cloudflare Pages with Wrangler CLI, Cloudflare account ID and\nAPI token are required.\n\n1. Account ID: [Find account and zone IDs][linkCloudflareFindAccountAndZoneIDs]\n1. API token\n   1. [Create API token][linkCloudflareCreateAPIToken]\n   1. Use `Edit Cloudflare Workers` template\n   1. Update the `Token name`\n   1. Permissions:\n      1. Account - Cloudflare Pages - Edit\n      1. Remove other permissions\n   1. Include your account\n   1. Set a short-lived TTL\n   1. Click `Continue to summary`\n1. These values will be used in the following section `1. Envfile`\n\n#### 1. Envfile\n\nThe following sections use the values from the file `.env`. Create file `.env`\n(based on `env.template`) with the correct values.\n\nExample:\n\n```bash\n# .env\nENV_CLOUDFLARE_BRANCH_NAME=main\nENV_CLOUDFLARE_PROJECT_NAME=random-project-name\nENV_SECRET_CLOUDFLARE_ACCOUNT_ID=id-from-previous-section\nENV_SECRET_CLOUDFLARE_API_TOKEN=token-from-previous-section\n```\n\nVerify:\n\n```bash\nmake shell\n# Check the env vars are correctly set\nenv | grep ENV_\n# List current projects on CloudFlare\ndeno task deploy:list\nexit\n```\n\n#### 2. Create\n\nThis section creates a new Pages project. This step is only needed if\n`ENV_CLOUDFLARE_PROJECT_NAME` wasn't listed in step `1. Envfile`.\n\n```bash\nmake shell\n# Create a new project\ndeno task deploy:create\n# The new project and its domain should be listed\ndeno task deploy:list\n# Project is empty which should not be hosted\ncurl -I https://${ENV_CLOUDFLARE_PROJECT_NAME}.pages.dev\n#HTTP/2 522\n#...\n# Exit the container\nexit\n```\n\n#### 3. Deploy\n\nThis section deploys the website to an existing Cloudflare Pages project.\n\n```bash\nmake shell\n# Deploy the files to the project\ndeno task deploy\n# Project is no longer empty!\ncurl -I https://${ENV_CLOUDFLARE_PROJECT_NAME}.pages.dev\n#HTTP/2 200\n#...\n# Exit the container\nexit\n```\n\nNote: `make deploy` can also be used.\n\n#### 4. Delete\n\nThis section shows how to delete a Cloudflare Pages project.\n\n```bash\nmake shell\ndeno task deploy:delete\n#? Are you sure you want to delete \"\u003cENV_CLOUDFLARE_PROJECT_NAME\u003e\"? This action cannot be undone. › y\n# Check the project is no longer listed\ndeno task deploy:list\nexit\n```\n\n\u003e [!IMPORTANT]\n\u003e The CloudFlare token created in section\n\u003e `0. Cloudflare account ID and API token` can be deleted\n\n### CI/CD\n\n[GitHub Actions][linkGitHubActions] is used to test PRs and deploy changes made\nto `main` branch to Cloudflare Pages.\n\n- A dedicated Cloudflare API token has been created for Github Actions\n- Environment variables required for deploying to Cloudflare Pages are set as\n  [variables][linkGitHubActionsVariables] and\n  [secrets][linkGitHubActionsSecrets] in GitHub Actions\n- The GitHub Actions workflows follow the 3 Musketeers pattern\n\n### Visual elements\n\n- 3 Musketeers logo\n  - Created by me with [Procreate][linkProcreate] and Vectornator\n    - Neat tools used are `offset path` and `mask objects`\n  - 2048px by 2048px SVG image\n  - Images are in folder `./src/assets/logo/`\n- Favicon\n  - Source image is an exported png format of the logo\n  - Use the website [favicon.io][linkFaviconio]\n  - The generated content is in `./public/favicon_io`\n  - Instructions to copy HTML `\u003clink\u003e` tags into the `\u003chead\u003e` was set in\n    `./astro.config.mjs`\n- Social media preview\n  - This is for displaying preview of the website on Twitter, Facebook, GitHub,\n    etc\n  - Created a new vector image 1280x640px with the scale down logo at the center\n    - The size is suggested by GitHub in General settings\n  - According to [artegence article][linkArtegenceArticle], the ideal image that\n    works on different social platforms\n    - Is 1200x630px\n    - Has the logo (630x630) centered\n    - Use png format (very high quality and transparency)\n    - Use jpg format (high quality and very good size compression)\n  - The social image is also set in the general settings of the repository\n  - Astro Startlight sets all of the `\u003cmeta\u003e` tags in the `\u003chead\u003e` section\n- Diagrams\n  - [Mermaid][linkMermaid] is used to generate diagrams\n  - All diagrams are in the directory [diagrams](diagrams)\n- The [demo][linkDemo] was generated by [charmbracelet/vhs][linkVHS]\n\n## Contributing\n\n[CONTRIBUTING.md](CONTRIBUTING.md)\n\nThanks goes to [contributors][linkContributors].\n\n## License\n\n[MIT][linkLicense]\n\n[link3Musketeers]: https://3musketeers.pages.dev\n[linkArtegenceArticle]: https://artegence.com/blog/social-media-tags-guide-part-2-preparing-a-perfect-image-for-the-ogimage-tag/\n[linkAstroStarlight]: https://starlight.astro.build/\n[linkCloudflareCreateAPIToken]: https://dash.cloudflare.com/profile/api-tokens\n[linkCloudflareDirectUpload]: https://developers.cloudflare.com/pages/get-started/direct-upload/\n[linkCloudflareFindAccountAndZoneIDs]: https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/\n[linkCloudflarePages]: https://pages.cloudflare.com/\n[linkCloudflareWranglerCICD]: https://developers.cloudflare.com/workers/wrangler/ci-cd/\n[linkCloudflareWranglerCLI]: https://developers.cloudflare.com/workers/wrangler/\n[linkCompose]: https://docs.docker.com/compose\n[linkContributors]: CONTRIBUTORS\n[linkDemo]: demo\n[linkDocker]: https://www.docker.com\n[linkFaviconio]: https://favicon.io\n[linkGitHubActions]: https://github.com/features/actions\n[linkGitHubActionsProject]: https://github.com/flemay/3musketeers/actions\n[linkGitHubActionsProjectBadge]: https://img.shields.io/github/actions/workflow/status/flemay/3musketeers/deploy.yml?style=for-the-badge\u0026logo=github\n[linkGitHubActionsSecrets]: https://docs.github.com/en/actions/security-guides/encrypted-secrets\n[linkGitHubActionsVariables]: https://docs.github.com/en/actions/learn-github-actions/variables\n[linkLicense]: LICENSE\n[linkLicenseBadge]: https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge\n[linkMake]: https://www.gnu.org/software/make\n[linkMermaid]: https://mermaid.js.org/\n[linkPatternOverview]: ./docs/guide/assets/diagrams-overview.svg\n[linkProcreate]: https://procreate.art/\n[linkVHS]: https://github.com/charmbracelet/vhs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflemay%2F3musketeers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflemay%2F3musketeers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflemay%2F3musketeers/lists"}