{"id":13814963,"url":"https://github.com/easychen/docker2saas","last_synced_at":"2025-04-04T16:15:10.033Z","repository":{"id":39966138,"uuid":"338511774","full_name":"easychen/docker2saas","owner":"easychen","description":"An open source tool that lets you create a SaaS website from docker images in 10 minutes.","archived":false,"fork":false,"pushed_at":"2022-01-18T01:45:54.000Z","size":8610,"stargazers_count":797,"open_issues_count":5,"forks_count":109,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-03-28T15:08:35.636Z","etag":null,"topics":["digitalocean","docker-compose","laravel","saas-boilerplate","stripe-api"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easychen.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":"2021-02-13T06:23:12.000Z","updated_at":"2025-03-17T16:26:09.000Z","dependencies_parsed_at":"2022-06-25T18:04:00.923Z","dependency_job_id":null,"html_url":"https://github.com/easychen/docker2saas","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/easychen%2Fdocker2saas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fdocker2saas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fdocker2saas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fdocker2saas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easychen","download_url":"https://codeload.github.com/easychen/docker2saas/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247208151,"owners_count":20901570,"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":["digitalocean","docker-compose","laravel","saas-boilerplate","stripe-api"],"created_at":"2024-08-04T04:02:47.742Z","updated_at":"2025-04-04T16:15:10.016Z","avatar_url":"https://github.com/easychen.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"\u003cimg src=\"public/brand.svg\" width=\"360\"/\u003e\n\n\n[简体中文](./README.zh-cn.md)\n\n# Screenshots\n\nfor members ( who subscribe the plan )\n\n![index](./_image/screen1.png)\n![pricing](./_image/screen5.png)\n![subscription](./_image/screen6.png)\n\nfor admin\n\n![settings](./_image/screen2.png)\n![members](./_image/screen3.png)\n![plans](./_image/screen4.png)\n![droplets](./_image/screen7.png)\n\n\n⚠️ This document was translated into English by deepl and can be improved by PR\n\n\u003e An open source tool that lets you create SaaS websites from images in as\nlittle as 10 minutes.\n\nDocker2SaaS is a tool that enables multi-tenancy through virtualization\ntechnology (calling cloud platform api ) with tenant management and subscription\nmanagment.  It helps web application and service developers to quickly build\nwebsites for sale or subscription. All you need to do is make an image of your application and\nthen set up and configure a Docker2SaaS site to start selling your application as a service.\n\nWhen a user's subscription is successful, it automatically creates a VPS from\nthe image as configured; when the user cancels the subscription and it expires,\nit automatically deletes the VPS. Users can login to the site and see their\nsubscription, host IP information, and other details. Additional extensions can be\nadded.\n\nThe diagram below shows how Docker2SaaS interacts between:\nEnd Users  \nPayment provider: Stripe \nCloud service provider: DigitalOcean.\n\n![](./_image/mm1.png)\n\n# Target Users of Docker2SaaS\n\nDocker2SaaS is aimed at developers of cloud applications, providing them with a\nsolution to quickly monetize their applications.\n\nLet's say you develop a nice little web app and open source it to Github.\nDevelopers easily build it and use it on their own, but as the app becomes more\npopular, so do non-technical users. But even if they have already made a docker\nfile, it is still difficult for them.\n\nAt this point you may want to provide a cloud hosting version. On the one hand,\nyou can solve the details of the build for non-technical users, and on the other\nhand, hosting can bring some profit, so you can get a financial return.\n\nHowever, this can create an additional amount of development, and it doesn't\nseem wise to spend weeks on development before you know if cloud hosting will be\npopular.\n\nFortunately, the open source Docker2SaaS solves this problem, and it only takes\nten minutes to configure and you can get a simple and usable cloud hosting sales\nsite. It's **immediately ready for early sales**, and you can modify the source code\nto add more business-related features as user demand increases. \n\nOf course, it can also be used to build a third-party sales site under the\nlicense of a cloud application developer. But overall, Docker2SaaS is designed\nfor developers and does not take into account the experience of non-technical\nusers, so if you don't have a technical background, it's better to use a\nDocker2SaaS site that someone else has built rather than building it yourself.\n\nPS: Docker2SaaS is built on Laravel, and while no knowledge is required for a\nsimple deployment, if you want to customize and add features, then you need to\nhave a little Laravel development knowledge.\n\nDocker2Saas is licensed under the GPLv2 with an additional non-compete clause. \n\n## Docker2SaaS Guide\n\n## Steps\n\n![](./_image/mm2.png)\n\n## Digital Ocean configuration \n### Create a Digital Ocean image \nWe assume that you have already made a docker image of your application and can start it with the docker-compose command. Let's use Ghost as an example to explain.\n\nFirst we will create a droplet（ Digital Ocean calls its VPS droplet  ） on Digital Ocean and select `docker on ubuntu` under `marketplace`.\n\n![](./_image/2021-02-13/2021-02-13-23-19-50.png)\n\nThen we log in to the newly created instance via SSH. Create our docker-compose.yaml file in the root directory (or somewhere else). Here we use the yaml provided by bitnami.\n\n```yml\n\nversion: '2'\nservices:\n  mariadb:\n    restart: always\n    image: 'docker.io/bitnami/mariadb:10.3-debian-10'\n    environment:\n      - ALLOW_EMPTY_PASSWORD=yes\n      - MARIADB_USER=bn_ghost\n      - MARIADB_DATABASE=bitnami_ghost\n    volumes:\n      - 'mariadb_data:/bitnami'\n  ghost:\n    restart: always\n    image: 'docker.io/bitnami/ghost:3-debian-10'\n    environment:\n      - MARIADB_HOST=mariadb\n      - MARIADB_PORT_NUMBER=3306\n      - GHOST_DATABASE_USER=bn_ghost\n      - GHOST_DATABASE_NAME=bitnami_ghost\n      - ALLOW_EMPTY_PASSWORD=yes\n      - GHOST_HOST=localhost\n      - GHOST_EMAIL=guest@ftqq.com\n      - GHOST_PASSWORD=admin\n    ports:\n      - '80:2368'\n    volumes:\n      - 'ghost_data:/bitnami'\n    depends_on:\n      - mariadb\nvolumes:\n  mariadb_data:\n    driver: local\n  ghost_data:\n    driver: local\n```\nNote that we have added `restart: always` to ensure that docker is started automatically when the image is started.\n\nOnce the file is created, go to droplet management and create a snapshot.\n\n![](./_image/2021-02-13/2021-02-13-23-37-10.png)\n\nWhen you are done creating the snapshot, you can delete the droplet instance.\n\nGo to the images page and look up the data-id of the snapshot in the source code corresponding to the snapshot entry you just created, this value (78661121 in the image) is the id of the snapshot. Record it, and we'll use it later. (We'll call this A1)\n\n![](./_image/2021-02-13/2021-02-13-23-45-41.png)\n\n### Creating a Digital Ocean Token\n\nNext we will create a token so that we can manage droplet through the API. At the bottom of the left menu, select API. \n\n![](./_image/2021-02-13/2021-02-13-23-53-39.png)\n\nIn the Tokens/Keys tab, generate a new token with the read \u0026\u0026 write permissions selected.\nOnce generated, record it and you will need it later. (We'll call it A2)\n\n## Stripe Configuration\nThe following are all described in Test mode. \n\n### Create a subscription\nGo to the Stripe dashboard and create a [product](https://dashboard.stripe.com/test/products/create).\n\nNote that in the Pricing section, select Recurring so that it will automatically renew. Fill in the rest of the fields as you wish.\n\n![](./_image/2021-02-13/2021-02-14-00-04-48.png)\nAfter creating the product, go to the product details page, and you can see the API ID in the Pricing section, and record it. (We'll write it down as B1)\n![](./_image/2021-02-13/2021-02-14-00-06-59.png)\n\nYou can create as many prices as you need, remember to record the price ids.\n\n### Get API key\nIn order to interact with the Stripe platform through the API, we also need the API key. click the Developer menu on the left, select API Keys, and record the publishable key and secret key on the right. (Note B2, B3)\n\n![](./_image/2021-02-13/2021-02-14-00-09-38.png)\nSince then, the preparation is done.\n\n## Configuring Docker2SaaS\n\n\n### Site initialization\n\nDownload/clone the docker2saas source code to the environment where you want to run the sales site. This environment needs to be configured with PHP7.4+ and MySQL.\n\n```bash\ngit clone https://gitlab.com/easychen/docker-2-saas.git --depth=1 docker2saas\n```\n\nInitialization of dependency packages：\n\n```bash\ncd docker2saas \ncomposer install\n```\n\nRename `.env.example` to `.env` and run the command to generate APP_KEY\n\n```bash\nphp artisan key:generate\n```\n\nFill in other relevant information.\n\n1. APP_DEBUG : should be set to false after debugging is completed \n2. APP_URL : Website URL\n3. APP_LOGO_URL and APP_ICON_URL: Home page big picture and top menu icon\n4. DB_*: database related configuration\n5. STRIPE_KEY: the B2 in the previous article\n6. STRIPE_SECRET: B3 in the previous section\n\n![](./_image/2021-02-13/2021-02-14-10-49-57.png)\n\nAfter creating the database docker2saas in MySQL, then run the command to initialize the database.\n\n```bash\nphp artisan migrate\n```\nStart the development environment\n\n```bash\nphp artisan serve --host=0.0.0.0 --port=8001\n```\n\nYou can see the website by accessing port 8001 of the machine ip. Click register to register users and login automatically, the first registered user will become administrator automatically.\n\nThe administrator's logic can be modified in `app/Providers/AuthServiceProvider.php`.\n\n```php\nGate::define('saas-admin', function (User $user) {\n            return $user-\u003eid == 1;         \n});\n```\n\n### Configure the site\n\nClick on the settings tab to configure the basic information for the site, where `DigitalOcean token` is A2 from above.\n\nThe `DigitalOcean sshkey` is the public key you want to use to manage all droplets. if you don't have one ready, you can create one by running the following command.\n\n```bash\nssh-keygen -t rsa  -f \u003cname\u003e\n```\nDuring the run, if you don't want to set the passphrase, you can just press enter twice to set it to empty.\n\n```\nssh-keygen -t rsa  -f this\nGenerating public/private rsa key pair.\nEnter passphrase (empty for no passphrase): \nEnter same passphrase again: \n\n```\n\nWhen this is done, \u003cname\u003e.pub will be generated in the command directory, and its contents will be the sshkey we want to fill in the form.\n\n\n![](./_image/2021-02-13/2021-02-14-12-08-09.png)\n\n\n### Create a subscription plan\n\nClick `Add a plan` on the `Plans` page to add a subscription plan.\n\n\n![](./_image/2021-02-13/2021-02-14-12-20-07.png)\n1. Name: the name of the plan visible to the user, e.g. pro\n2. Stripe Price ID: B1 in the previous article\n3. DigitalOcean Droplet Region: the region where the created cloud host is located \n4. DigitalOcean Droplet Size: the model of the created cloud host\n\nThe region and size values can be obtained from the Digital Ocean official website on the Create Droplet page. After you have selected the desired region and model, the default name of the generated cloud host is the size in the selected section as shown below, followed by the `sgp1` section which is the region.\n![](./_image/2021-02-13/2021-02-14-12-25-50.png)\n1. DigitalOcean Droplet Image: A1 in the previous section\n2. DigitalOcean Droplet User Data: Custom information that can be accessed in the cloud host, which can be used to pass information about the purchased user, such as email, etc. The details of what is used will be explained later. You can leave it blank for now.\n\n![](./_image/2021-02-13/2021-02-14-12-32-53.png)\n\nAfter saving, you will get a Link in the list screen, which you can click to enter the subscription process of the plan. (This link is called C1)\n\nClick on the `Pricing` page to see a preset plan display page.\n\n![](./_image/2021-02-13/2021-02-14-12-38-27.png)\nThis page can be customized by editing `resources/views/pricing.blade.php`. This page uses the [blade](https://laravel.com/docs/8.x/blade) syntax, but is composed almost entirely of HTML, so it is not too difficult to modify.\n\nIn addition to modifying the style and service offerings, you should pay special attention to the `Subscribe` button below, which should link to the corresponding plan, as in C1 above.\n\nSimilarly, edit `resources/views/dashboard.blade.php` to modify the `dashboard` page that users see after registering, where you can add instructions and help related to the cloud service.\n\n### Other configuration items\n\n#### Timed tasks\n\nDocker2Saas monitors expired users daily and removes their cloud hosts. To be able to execute it regularly, you need to add the commands for this item to the system crontab:. macos/deepLFree.translatedWithDeepL.text\n\n```\n* * * * * php \u003c/path/to/docker2saas\u003e/artisan schedule:run\n```\n\n#### Webhook\nSince users can modify their subscriptions on the Stripe website, subscription modifications and payment confirmations in Docker2Saas are done via webhook.\n\nThe webhook requires an externally accessible URL, which is recommended to be configured after going live. If you are debugging locally, you can use ngrok for intranet penetration.\n\nSuppose the URL of Docker2Saas website is `http://D.com`, then the webhook endpoint URL is `http://D.com/stripe/webhook`.\n\n![](./_image/2021-02-13/01.png)\n\nSelect the following events at events to send.\n\n1. invoice.created\n2. invoice.paid\n3. invoice.payment_action_required\n4. customer.subscription.created\n5. customer.subscription.updated\n6. customer.subscription.deleted\n7. customer.created\n8. customer.updated\n9. customer.deleted\n\nNote that the `customer.subscription.updated` is a subscription change, which is not handled by default as it involves the specific hierarchy logic behind the cloud application. You can implement it yourself in `app/Http/Controllers/WebhookController.php`.\n\nAt this point, the site is ready for normal transactions. Note that here we are using develop server for debugging, and in order to support more users, you should switch to dedicated server software such as Nginx. For details, please [refer here](https://laravel.com/docs/8.x/deployment).\n\n#### Initializing a mirror using user data\n\nIn a Ghost mirror, we need to know the IP address or domain name of the current droplet to configure the connection path; we also need to know the email address of the user to create a default account for them.\n\nSo we need a way to get user information in the mirror. When creating the plan above, we have a user data option (noted as F1) that is used to do just that.\n\n![](./_image/2021-02-13/2021-02-14-12-20-07.png)\nThis is a mechanism [provided by Digital Ocean](https://www.digitalocean.com/docs/droplets/how-to/provide-user-data/), in all droplets, just visit `http:// 169.254.169.254/metadata/v1/user-data` to get the information passed in during creation.\n\n![](./_image/mm3.png)\n\nYou can view it in droplet with the curl command.\n\n```bash\ncurl http://169.254.169.254/metadata/v1/user-data\n```\nBut there is a problem that each user has a different email address. So we need to have variables to support when we fill in the F1 place. Here Docker2Saas provides `$user` variables via the blade syntax, so you can insert the user id via `{{$user-\u003eid}}` and the email via `{{$user-\u003eemail}}`.\n\n```\nuid={{$user-\u003eid}}\n```\n\nYou can even put the `docker-compose.yml` template directly at F1.\n\nOf course, in the droplet image, you also need to configure the appropriate startup script to get this data and configure it.\n\nIn addition, through `curl http://169.254.169.254/metadata/v1` you can also get droplet related information, such as ip, domain name, etc. For the specific format, please refer to the [related documentation](https://www.digitalocean.com/docs/droplets/how-to/retrieve-droplet-metadata/).\n\n\n# License\n\nThis project uses the GPLv2 License with conditions.\n\nBoth individuals and commercial companies can use Docker2SaaS to build their own cloud application sales sites under the GPLv2 license.\n\nHowever, selling Docker2SaaS itself as a Cloud Hosting service (e.g., making Docker2SaaS an image and selling it as a cloud service through Docker2SaaS or other platforms) is prohibited.\n\n\n\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fdocker2saas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasychen%2Fdocker2saas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fdocker2saas/lists"}