Giter Site home page Giter Site logo

saaskit's Introduction

Deno SaaSKit

Warning: this project is in beta. Design, workflows, and user accounts are subject to change.

Discord Chat

Deno SaaSKit is an open-sourced, highly performant template for building your SaaS quickly and easily.

Features

Want to know where Deno SaaSKit is headed? Check out our roadmap.

Getting Started Locally

Prerequisites

Setup the repo

  1. Clone the repo:
git clone https://github.com/denoland/saaskit.git
cd saaskit
  1. Create a .env file to store environmental variables:
cp .example.env .env

Auth (Supabase)

The values of these environmental variables will be gathered in the following steps.

  1. While Docker is running, start the Supabase services:
supabase start
  1. Copy the values of the printed Supabase API URL and anon key variables into the environmental variables in your .env file as SUPABASE_URL and SUPABASE_ANON_KEY, respectively.

Payments and Subscriptions (Stripe)

  1. Copy your Stripe secret key as STRIPE_SECRET_KEY into your .env file. We recommend using the test key for your development environment.
  2. Run deno task init:stripe and follow the instructions. This automatically creates your "Premium tier" product and configures the Stripe customer portal.

Note: go to tools/init_stripe.ts if you'd like to learn more about how the init:stripe task works.

  1. Listen locally to Stripe events:
stripe listen --forward-to localhost:8000/api/stripe-webhooks --events=customer.subscription.created,customer.subscription.deleted
  1. Copy the webhook signing secret to .env as STRIPE_WEBHOOK_SECRET.

Running the Server

Finally, start the server by running:

deno task start

Go to http://localhost:8000 to begin playing with your new SaaS app.

Note: You can use Stripe's test credit cards to make test payments while in Stripe's test mode.

Customization

Global Constants

The utils/constants.ts file includes global values used across various aspects of the codebase. Update these values according to your needs.

Blog

To create a new blog post, create a Markdown (.md) file within /data/posts/ with the filename as the slug. E.g. /data/blog/hello-there.md will correspond to the /blog/hello-there route. See /data/posts/ for examples.

Post properties are to be added to the starting Front Matter section of the Markdown file. See the Post interface in /utils/posts.ts for a full list of properties and their types.

Themes

You can customize theme options such as spacing, color, etc. By default, Deno SaaSKit comes with primary and secondary colors predefined within twind.config.ts. Change these values to match your desired color scheme.

Deploying to Production

This section assumes that a local development environment has been set up.

Authentication (Supabase)

These steps enable using email with Supabase Auth.

In your Supabase dashboard:

  1. Go to your project
  2. Go to Authentication > Providers > click Email
  3. Disable Confirm email
  4. Go to Authentication > URL Configuration
  5. Set the Site URL to be https://{{ YOUR DOMAIN }}/login/success and click Save
  6. Click Add URL under Redirect URLs and set the URL to be https:// {{ YOUR DOMAIN }}/**

If you'd like to use additional social OAuth authentication strategies, please refer to the Supabase Auth documentation.

Supabase Production Environmental Variables

The following can be found in Dashboard Home -> Settings -> API -> API Settings/Project API Keys

  • SUPABASE_ANON_KEY under anon public
  • SUPABASE_API_URL under URL

Payments (Stripe)

In order to use Stripe in production, you'll have to activate your Stripe account.

Once your Stripe account is activated, simply grab the production version of the Stripe Secret Key. That will be the value of STRIPE_SECRET_KEY in prod.

Automate Stripe Subscription Updates via Webhooks

Keep your user's customer information up-to-date with billing changes by registering a webhook endpoint in Stripe.

  • Endpoint URL: https://{{ YOUR DOMAIN }}/api/stripe-webhooks
  • Listen to Events on your account
  • Select customer.subscription.created and customer.subscription.deleted

Stripe Production Environmental Variables

  • STRIPE_SECRET_KEY: Dashboard Home (Right Side of Page) -> Secret Key (only revealed once)
  • STRIPE_WEBHOOK_SECRET: Dashboard Home -> Developers (right side of page) -> Create webhook -> Click Add Endpoint
    • After Creation, redirected to new webhook page -> Signing Secret -> Reveal
  • STRIPE_PREMIUM_PLAN_PRICE_ID: Dashboard -> Products -> Premium Tier -> Pricing/API ID

Stripe Customer Portal Branding

Set up your branding on Stripe, as the user will be taken to Stripe's checkout page when they upgrade to a subscription.

Using Docker to Deploy to any VPS

Docker makes it easy to deploy and run your Deno app to any virtual private server (VPS). This section will show you how to do that with AWS Lightsail and Digital Ocean.

Setting up Docker

Install Docker on your machine, which should also install the docker CLI.

Create an account on Docker Hub, a registry for Docker container images.

Create a Dockerfile in the root of your repo:

FROM denoland/deno:1.32.4

EXPOSE 8000

WORKDIR /app

ADD . /app

# Add dependencies to the container's Deno cache
RUN deno cache main.ts --import-map=import_map.json
CMD ["run", "--allow-run", "--allow-write", "--allow-read", "--allow-env", "--allow-net", "main.ts"]

Create a .dockerignore file in the root folder of your repo to make sure certain files are not deployed to the docker container:

README.md
.example.env
.vscode/
.github/

A docker-compose.yml file will be needed to run the docker file on a VPS. Here’s what that file in your repo's root folder will look like:

version: '3'

services:
  web:
    build: .
    container_name: deno-sasskit
    image: deno-image
   environment:
     - DENO_DEPLOYMENT_ID=${DENO_DEPLOYMENT_ID}
     - SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
     - SUPABASE_API_URL=${SUPABASE_API_URL}
     - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
     - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
     - STRIPE_PREMIUM_PLAN_PRICE_ID=${STRIPE_PREMIUM_PLAN_PRICE_ID}
    ports:
      - "8000:8000"

The values of the environmental variables are pulled from the .env file.

The DENO_DEPLOYMENT_ID variable is needed for Docker deployment of a Deno Fresh app for caching to work properly. Its value needs to be a unique id tied to the deployment. We recommend using the SHA1 commit hash, which can be obtained from the following command run in the repo's root folder:

# get the SHA1 commit hash of the current branch
git rev-parse HEAD

Automatic Deployment with Deno Deploy

These steps show you how to deploy your SaaS app close to your users at the edge with Deno Deploy.

  1. Clone this repository for your SaaSKit project.

  2. Sign into Deno Deploy with your GitHub account.

  3. Select your GitHub organization or user, repository, and branch

  4. Select "Automatic" deployment mode and main.ts as the entry point

  5. Click "Link", which will start the deployment.

  6. Once the deployment is complete, click on "Settings" and add the production environmental variables, then hit "Save"

You should be able to visit your newly deployed SaaS.

Deno Deploy via GitHub Action

You can also choose to deploy to Deno Deploy via a GitHub Action, which offers more flexibility. For instance, with the GitHub Action, you could:

  • Add a build step
  • Run deno lint to lint your code
  • Run deno test to run automated unit tests
  1. Create a new, empty project from the Deno Deploy dashboard. Set a name for your project.

  2. Add the GitHub Action.

GitHub Actions are configured using a .yml file placed in the .github/workflows folder of your repo. Here's an example .yml file to deploy to Deno Deploy. Be sure to update the YOUR_DENO_DEPLOY_PROJECT_NAME with one that you've set in Deno Deploy.

# Github action to deploy this project to Deno Deploy
name: Deploy
on: [push]

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # Needed for auth with Deno Deploy
      contents: read  # Needed to clone the repository

    steps:
      - name: Clone repository
        uses: actions/checkout@v3

      - name: Install Deno
        uses: denoland/setup-deno@main
        # If you need to install a specific Deno version
        # with:
        #   deno-version: 1.32.4

## You would put your building, linting, testing and other CI/CD steps here

## Finally, deploy
      - name: Upload to Deno Deploy
        uses: denoland/deployctl@v1
        with:
          project: YOUR_DENO_DEPLOY_PROJECT_NAME
          entrypoint: main.ts
          # root: dist
          import-map: import_map.json
          exclude: .git/** .gitignore .vscode/** .github/** README.md .env .example.env
  1. Commit and push your code to GitHub. This should trigger the GitHub Action. When the action successfully completes, your app should be available on Deno Deploy.

Deploying to Amazon Lightsail with Docker

In order to deploy your Docker image to Amazon Lightsail you need to create an AWS account if you don’t already have one.

  1. The deployment process starts with a local Docker image build which requires that the Dockerfile and docker-compose.yml have beed created as above:
docker compose -f docker-compose.yml build
  1. Tag your image locally using the following command:
docker tag deno-image {{ username }}/deno-saaskit-aws

The name deno-image comes from your docker-compose.yml file.

  1. The tagged image needs to be registered on Docker Hub. In order to do that, sign into your Hub account (or create one if you don’t have one).

  2. Push the tagged image to Docker Hub. We have chosen the name deno-saaskit-aws which you can change. Substitute {{username}} with your Docker Hub username.

docker push {{ username }}/deno-saaskit-aws

You should then be able to see your image on Docker Hub where it can be picked up by the AWS container service.

  1. Go to the AWS LIghtsail Create a Container Service landing page. On that page you can choose a server location and service capacity or keep the defaults.
  • Click on “Setup deployment” and choose “Specify a custom deployment” which will result in the display of a form. Here’s what you need to fill out:

    • Container name: Give it a name of your choosing.
    • Image: Use the Docker Hub name {{username}}/deno-saaskit-aws.
    • Open Ports: Click “Add open ports” and then enter “8000” as the port.
    • Environmental Variables: Enter the name and values of all production environmental variables from .env.
    • Public Endpoint: Select the container name you just entered.

Under “Identify your service”, enter a container service name of your choosing. It will become part of the app's domain.

  1. Click the “Create Container Service” button. It will take some time for the deployment to complete. You will see a "Deployed” message when it is finished.

After the deployment is complete, click on the public address link and you'll see your app running in the browser.

Deploying to Digital Ocean with Docker

To deploy your image to Digital Ocean, you will need A Digital Ocean account and the doctl CLI installed and validated locally.

  1. Build the Docker image locally and tag it for a Digital Ocean Container Registry. This requires that you have created Dockerfile and docker-compose.yml files as instructed above
# Local Docker build
docker compose -f docker-compose.yml build
# Tag for DO container registry (separate from Docker Hub)
docker tag deno-image registry.digitalocean.com/deno-saaskit/deno-image:new
  1. Push your tagged image to your DO container registry.
doctl registry login -t {{ API Access Token }}
  • Create a Digital Ocean Container Registry named deno-saaskit:
doctl registry create deno-saaskit

Alternatively, you can create the container registry online.

  • Push the image to Digital Ocean’s registry (make sure you are logged in using doctl registry login).
docker push registry.digitalocean.com/deno-saaskit/deno-image:new

You should now be able to see your image in the DO Container Registry.

  1. Once the deno-image has been pushed to the Digital Ocean registry we can run it in a Digital Ocean Droplet. Go to your Digital Ocean project page and click the 'Create' button and select 'Droplets'.

  2. When the droplet is created, use the console link on your droplet page to SSH to the droplet VM or use SSH locally run this command:

docker run -d --restart always -it -p 8000:8000 --name deno-image registry.digitalocean.com/deno-on-digital-ocean/deno-image:new

The URL will be visible once the command completes. Use the droplet's IP address with port 8000 to browse to your application deployed on Digital Ocean.

Contributing

When submitting a pull request, please follow the Deno Style Guide.

Before submitting, run the following to check the formatting, linting, licenses, and types and run tests in one hit:

deno task ok

Goals and Philosophy

For the user, the website should be fast, secure and have a design with clear intent. Additionally, the HTML should be well-structured and indexable by search engines. The defining metrics for these goals are:

For the developer, the codebase should minimize the steps and amount of time required to get up and running. From there, customization and extension of the web app should be simple. The characteristics of a well-written codebase also apply, such as:

  • Easy to understand
  • Modular functionality
  • Clearly defined behavior with validation through tests

Community and Resources

Join the #saaskit channel in Deno's Discord to meet other SaaSKit developers, ask questions, and get unblocked.

Here's a list of articles, how to guides, and videos about SaaSKit:

saaskit's People

Contributors

cdoremus avatar chris-james avatar huai-jie avatar iuioiua avatar lambtron avatar niklasmtj avatar rroblf01 avatar thorwebdev avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.