- Downloading Boutique (& Copying it to Your Server)
- Creating a PostgreSQL Database
- Running `boutique --install`
- Proxying via Nginx
- Starting and Stopping Boutique
- Setting up Stripe Webhooks
- Setting up AWS SES and SNS Webhooks
- Getting Started with Boutique
- Creating a Product
- Creating a Newsletter
- Customizing the Embedded Modal
- Email Templates
- Forgot Your Password
- Updating Boutique
- Backing Up Boutique
- Other Questions
Downloading Boutique (& Copying it to Your Server)
After purchase, you can download the Boutique binary to your computer from this website.
Use scp
to upload it to your server:
local$ scp /path/to/downloads/boutique-linux-amd64 example.com:.
local$ ssh example.com
server$ sudo mkdir -p /usr/local/bin
server$ sudo cp boutique-linux-amd64 /usr/local/bin/boutique
Please make sure the /usr/local/bin
directory is within your $PATH
.
Creating a PostgreSQL Database
Make sure you have a user and database created for Boutique. The snippet below assumes you run
have a deploy
user that's used to run Boutique (or other web applications). It also
creates a boutique
database.
$ sudo -u postgres createuser deploy
$ sudo -u postgres createdb boutique
$ sudo -u postgres psql
postgres=# alter user deploy with encrypted password 'secret';
postgres=# grant all privileges on database boutique to deploy;
Running `boutique --install`
Before you start the installation process, grab these values from Stripe and AWS:
- Stripe Publishable Key — you can generate this key via your Stripe Dashboard
- Stripe Secret Key — the secret key that's generated with your publishable key
- AWS Access Key ID — you can generate this key via your AWS IAM Management Console, please make sure it has access to SES and SNS
- AWS Secret Access Key — the secret key that's generated with your access key id
- AWS Region — the AWS region that SES/SNS are operated in, eg
us-west-2
After you've copied the binary onto your server, start the install process by running:
$ boutique --install
You will be asked for the user running Boutique, the absolute path of Boutique, and the password for the Boutique admin panel. I suggest running Boutique as a non-root user for security, but it will also work if you use root.
Boutique will install the files /etc/systemd/system/boutique.service
and
/etc/systemd/system/boutiqueq.service
. These will be used to start the Boutique
server and queue anytime your server starts. Please double-check to make sure those files are
correct.
Next, Boutique will install configuration files into the ~/.boutique
directory. The
application is scoped to whichever user you selected earlier. Whenever you run Boutique, make
sure to run it as the installed user. You'll be asked to set some environment variables:
- BOUTIQUE_DB — the Postgres URL to connect to your database, for example:
postgres://username:password@localhost/boutique
- BOUTIQUE_URL — the public URL that Boutique will be hosted at, for example: https://boutique.example.com
- BOUTIQUE_STRIPE_PUBLISHABLE_KEY — the public Stripe key, prefixed with
pk_live
- BOUTIQUE_STRIPE_SECRET_KEY — the private Stripe key, prefixed with
sk_live
- BOUTIQUE_AWS_ACCESS_KEY_ID — the AWS public key
- BOUTIQUE__AWS_SECRET_ACCESS_KEY — the AWS secret key
- BOUTIQUE__AWS_REGION — the AWS region for SES/SES, for example
us-west-2
- BOUTIQUE_PORT — the port to run Boutique on, defaults to 3000
If you prefer to set environment variables a different way, you can comment out all lines in your Boutique config file.
Boutique will then generate the frontend assets (HTML, CSS, JavaScript, and images) and migrate your database.
Your admin credentials will be set to whatever email address you used to purchase Boutique and
the password you entered earlier. If you ever need to reset them, just run boutique --reset
.
Proxying via Nginx
You'll need to setup a web server to:
- point URL to
/home/user/.boutique/public
- serve HTML and other asset files
- serve
/admin/*
requests to all point to the index.html file - reverse proxy
/api/*
requests to the Boutique port
You can do that with Nginx or Apache. Here's an example on how to do that with Nginx:
# /etc/nginx/sites-enabled/nginx-*.conf, inside server block
listen 443 ssl;
listen [::]:443 ssl;
server_name boutique.example.com;
# to remove trailing slash
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
rewrite ^/([^.]*)/$ /$1 permanent;
# serve from this directory
root /home/deploy/.boutique/public;
index index.html;
# serve non-HTML asset files
location ~* \.(jpg|jpeg|png|css|js|eot|ttf|woff|woff2)$ {
expires max;
try_files $uri =404;
}
# reverse proxy API requests to port 3000
location ~ ^/api/.*$ {
proxy_pass http://localhost:3000;
}
# catch all /admin/* routes and serve index.html file
location ~ ^/admin.*$ {
try_files /index.html =404;
}
Starting and Stopping Boutique
Boutique systemd service files have been installed. To use them:
# start Boutique
$ sudo service boutique start
$ sudo service boutiqueq start
# stop Boutique
$ sudo service boutique stop
$ sudo service boutiqueq stop
Setting up Stripe Webhooks
Boutique requires a Stripe webhook to verify purchases. To set it up:
- Go to the Stripe Webhooks Dashboard
- Click the "+ Add Endpoint" button
- For the "Endpoint URL", put
https://boutique.example.com/api/webhook/purchases
(be sure to replace with your domain) - For "Events to Send", select "payment_intent.succeeded"
- Click "Add Endpoint"
Setting up AWS SES and SNS Webhooks
Boutique uses AWS SES to send emails and SNS to track email events (such as bounces and complaints). Any email you send from will need to be added to SES:
- Sign into your AWS Console
- In the top search bar, navigate to SES (Amazon Simple Email Service)
- In the left sidebar, navigate to "Email Addresses"
- Use the "Verify a New Email Address" and follow the steps for each email address you'll be sending from
You'll also need to setup SNS to call Boutique's webhook:
- Go to the AWS Console if you're not there yet
- In the top search bar, navigate to SNS (Amazon Simple Notification Service)
- In the left sidebar, click on "Topics"
- Click the "Create topic" button
- Select "Standard" for type and set the name to "boutique", click "Create topic" to finalize
- On the next page, click "Create subscription"
- Select HTTPS for the protocol and paste in
https://boutique.exmaple.com/api/webhook/emails
for the URL (be sure to replace with your domain)
Finally, you can connect SES to SNS via a configuration set. This is how AWS sends out notification on bounces, rejects, and complaints:
- Go to the AWS Console if you're not there yet
- In the top search bar, navigate to SES (Amazon Simple Email Service)
- In the left sidebar, navigate to "Configuration Sets"
- Click "Create Configuration Set" and create a set named "boutique"
- Click on the configuration set link to "boutique"
- Add destination to "SNS"
- Name it "boutique"
- Select event types: "Reject", "Bounce", "Complaint". If you want to track Open/Click, you can select those two also.
- For the Topic, select "boutique" (the topic you created earlier) and click "Save"
Getting Started with Boutique
After you've started boutique with service boutique start
and service boutiqueq start
,
it should start running on whatever port you've designated. After configuring Nginx/Apache to reverse
proxy to it, the admin panel should be available at:
https://boutique.example.com/admin # remember to replace with your domain name!
Go ahead to /admin
in your web browser. Log in with the email you used to purchase
Boutique and the password you set at the beginning of installation.
Creating a Product
Products are what you'll sell to your customers. You can upload files, add URLs, or even tell Boutique to run a script on your server to generate a file. After purchase, customers will have access to your product.
From the Boutique admin panel, click on "Products" in the sidebar and click "Add Product":
Name
— your product's name, shown to the customerCode
— URL slug for productPrice
— amount in USD you'll sell it forURL
— absolute URL of the product's homepageFrom Email
— SES verified email address you'll send receipts fromDescriptor
— text to show customer on their credit card statementDescription
— optional text to show in purchase modal
To further configure your product, you can click "Edit Product" from the "Actions" menu in the top right corner.
Once you've created a product, it will create a "Base" option for you. A single product can have different tiers, like Base/Plus/Premium. Each tier can have different price points and attached files. These tiers are called options in Boutique. You can add more options on this tab, or go to the "Assets" tab to upload a file.
Assets are what your customer will download after they purchase your product. A single product can have zero or more assets. From the "Assets" tab, you can upload files or add a link for your customers. You can attach them to options via the "Options" tab.
When you're satisfied with your uploads, go to the "Install" tab. This will have instructions on how to install the purchase modal on your website.
Creating a Newsletter
Newsletters are what your audience can subscribe to. After subscribing, they'll receive all drip emails and future broadcasts.
From the Boutique admin panel, click on "Newsletters" in the sidebar and click "Add Newsletter":
Name
— your newsletter's name, shown to the customerCode
— URL slug for newsletterURL
— absolute URL of your websiteAsk for Name?
— should the subscribe form ask for a nameFrom Email
— SES verified email address you'll send receipts fromDescription
— optional text to show in purchase modal
Additional properties can be found from the "Actions" -> "Edit Product" menu item in the top right corner. The "Schedule" tab will determine when your drip emails are sent out, these time slots are for your subscribers' timezone. The "Email" tab will let you customize email content and colors.
On the main newsletter screen, you can add drip and broadcast emails via their respective tabs. Drip emails are pre-written sequences that are sent out to subscribers based on a delayed amount of days. Broadcast emails are sent immediately to all current subscribers.
Go to the "Install" tab for instructions on how to install the subscribe modal to your website.
Customizing the Embedded Modal
The embedded modal can be customized with Boutique.configure({ settings... });
.
For example:
Boutique.configure({
primaryColor: "#3f8efa",
fontFamily: "sans-serif",
fontSize: "15px",
buyButton: "Purchase for {{price}}",
recoverButton: "Resend Email",
receiptHtml: "<p>Thank you! Your order was sent to {{email}}</p>",
subscribeConfirmHtml: "<p>An email was sent to {{email}}, please click the confirmation link in it to subscribe.</p>"
});
Theme and general settings available are:
primaryColor
— primary theme color used for links/buttons, defaults to "#3f8efa"outlineColor
— outline of focused form inputs, defaults to primaryColorlinkColor
— color of links, defaults to primaryColorlinkHoverColor
— color of links on hover, defaults to light linkColor by 15%linkActiveColor
— color of links on click, defaults to dark linkColor by 15%buttonTextColor
— color of button text, defaults to "#fff"fonts
— if the fontFamily property uses custom fonts, you'll need to pass them in here. These are forwarded to Stripe as CustomFontSource objectsfontFamily
— CSS for font-family, defaults to "Lucida Sans Unicode, Lucida Grande, sans-serif"fontSize
— CSS for paragraph font-size, defaults to "13px"headerFontFamily
— CSS for header's font-family, defaults to fontFamilyheaderFontSize
— CSS for header's font-size, defaults to "32px"formFontFamily
— CSS for form's font-family, defaults to system's UIformFontSize
— CSS for form's font-size, defaults to "13px"errorHtml
— message for generic error messages, use{{error}}
as a placeholder. Defaults to "<p>{{error}}</p>"
Product settings:
assetIcon
— boolean, show icons next to download links after customer purchases your product. Defaults to truebuyButton
— text shown to user on the buy modal button, defaults to "Pay {{price}}"buyButtonLock
— boolean, show the lock icon in the buy button, defaults to falserecoverButton
— text shown on the recover modal button, defaults to "Send Email"receiptHtml
— custom HTML for text shown after customer makes a purchase, has access to the{{email}}
placeholderrecoverHtml
— custom HTML for text shown for customer starting recovery process, shown above an email address input fieldrecoverConfirmHtml
— custom HTML for text shown after customer submits a recovery request. Should tell customer to check their email for a link. Has access to{{email}}
placeholderrecoveredHtml
— custom HTML for text shown after customer recovers a purchase, has access to the{{email}}
placeholderexpiredHtml
— custom HTML for text shown if customer clicks old link to download product, that has expiredhistory
— boolean, on receipt will change the browser's URL so customer can bookmark their purchase. Defaults to false
Newsletter settings:
subscribeButton
— text shown on subscribe form's button, defaults to "Subscribe"subscribeConfirmHtml
— custom HTML for text shown after customer submits their email address. Should direct customer to their email inbox to click on confirmation link. Has access to{{email}}
placeholdersubscribeAlreadySentHtml
— custom HTML shown if customer already tried to subscribe recently but has not confirmed yet. Has access to{{email}}
placeholdersubscribeAlreadyConfirmedHtml
— custom HTML shown if customer is trying to subscribe again but has already subscribed to this newsletter. Has access to{{email}}
placeholderunsubscribedHtml
— custom HTML shown after customer unsubscribes. Add an anchor withid="resubscribe-link"
to trigger re-subscribe on click. Has access to{{email}}
placeholderresubscribedHtml
— custom HTML showon after customer re-subscribes. Has access to{{email}}
placeholder
Email Templates
Content on email templates are configurable using a subset of the Liquid Templating Language, and Markdown with pass-through HTML.
Emails such as purchase receipts or newsletter subscribe confirmation can be customized by:
- going to the product/newsletter page
- clicking the "Actions" menu in the top right corner, then clicking "Edit"
- select the "Email" tab
- select "Template" or "Receipt/Recover/Subscribe Email Content"
Check the help text for each field to see what placeholders are available for each email (for
example {{price}}
or {{name}}
). If a placeholder includes
HTML, be sure to run it through the | safe
filter.
All Drip and Broadcast emails have access to these placeholders:
{{first_name}}
— customer/subscriber's first name if it exists{{full_name}}
— customer/subscriber's full name if it exists{{name}}
— customer/subscriber's first name, if doesn't exist then attempt the full name
Forgot Your Password
If you ever forget your password, ssh into your server and change to your deploy user. Then
run boutique --reset
to reset your password.
It's important to change to your deploy user before using the boutique
command,
since all configuration is stored under their home directory.
Updating Boutique
You can get the latest version of Boutique from this site.
Once you've downloaded the latest binary:
local$ scp /path/to/downloads/boutique-linux-amd64 example.com:.
local$ ssh example.com
server$ service boutique stop && service boutiqueq stop
server$ sudo cp boutique-linux-amd64 /usr/local/bin/boutique
server$ su deploy # change to whatever user runs Boutique
server$ boutique --migrate && boutique --generate
server$ service boutique start && service boutiqueq start
This will replace your current Boutique binary, restart the server/queue, run any updated database migrations, and generate new frontend assets (if any).
Backing Up Boutique
Backup the database used for Boutique and backup the ~/.boutique
directory (located
in the deploy user's home directory).
$ pg_dump boutique > boutique_db.bak
$ su deploy
$ cd && tar cfz boutique_config.tgz .boutique
Other Questions
Please contact me if you have any questions about Boutique.