Shopify / shopify-app-template-remix

356 stars 150 forks source link

Guide for Deploying in to AWS #319

Closed owlyowl closed 11 months ago

owlyowl commented 1 year ago

Issue summary

Seeing as AWS is such a big hosting provider, I was hoping to get some more information documented on how we could deploy the app in to the AWS environment.

Remix has the remix-grunge stack which seems to form a good basis for using cloudformation and eventually deploying in to a Lambda, but it is quite obfuscated away.

It would be really helpful if we could get some kind of official steps documented for deploying in to AWS if possible as this remains undocumented.

byrichardpowell commented 1 year ago

Hey @owlyowl

Thanks for opening this issue. I'm going to chat with the team and see what we can do here. Agree we want to make the documentation as useful as possible here.

owlyowl commented 1 year ago

Thank you Richard! Most appreciated.

I've currently run up the grunge stack and have looked at the Lambda application output and resulting cloudformation yaml. I'm now investigating to see if I can port this to the Shopify Remix App Template build pipeline.

Another approach would be docker to AWS Fargate but the lambda approach seems more straightforward.

I'll see if I can stand something up in either Arc or Terraform and get it working out of the box and get back to you.

In the meantime I really appreciate you looking into this :)

On Fri, Sep 1, 2023 at 4:28 AM Richard Powell @.***> wrote:

Hey @owlyowl https://github.com/owlyowl

Thanks for opening this issue. I'm going to chat with the team and see what we can do here. Agree we want to make the documentation as useful as possible here.

— Reply to this email directly, view it on GitHub https://github.com/Shopify/shopify-app-template-remix/issues/319#issuecomment-1701557190, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOT4CT6PFHK2FGBM276KUDXYDJTRANCNFSM6AAAAAA344VC5M . You are receiving this because you were mentioned.Message ID: @.***>

byrichardpowell commented 1 year ago

Thanks for the context @owlyowl

Chatted with the team and we want to add something. Just to set expectations; It might be a little while yet as we have some missing API's that we need to prioritize first.

JannikWempe commented 1 year ago

I am building a Remix Shopify app with SST. It is easy and very flexible. I love the experience. I have just used their drop-in mode after initializing the app using the CLI.

rodrigogsqquid commented 11 months ago

I am building a Remix Shopify app with SST. It is easy and very flexible. I love the experience. I have just used their drop-in mode after initializing the app using the CLI.

+1 to using SST. Amazing Development experience. You should try it @owlyowl

owlyowl commented 11 months ago

Thanks very much! I ended up rolling something because we're using Terraform.

I'm using a mix of the SST approach and the Remix Grunge Stack so it's Cloudfront (with origins/behaviours for static/server content) -> API Gateway v2 to proxy the root request through -> Lambda for the Remix server with a bespoke server.ts in the root to handle auth/cookies translation between API Gateway / Node and back.

On Thu, Nov 16, 2023 at 2:39 AM rodrigogsqquid @.***> wrote:

I am building a Remix Shopify app with SST https://docs.sst.dev. It is easy and very flexible. I love the experience. I have just used their drop-in mode https://docs.sst.dev/what-is-sst#drop-in-mode after initializing the app using the CLI.

+1 to using SST. Amazing Development experience. You should try it @owlyowl https://github.com/owlyowl

— Reply to this email directly, view it on GitHub https://github.com/Shopify/shopify-app-template-remix/issues/319#issuecomment-1812768672, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOT4CSBNWVMGAJJVVVVZE3YETO3NAVCNFSM6AAAAAA344VC5OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJSG43DQNRXGI . You are receiving this because you were mentioned.Message ID: @.***>

owlyowl commented 11 months ago

I ended up going: API Gateway with 2 origins defined:

  1. Route to S3 bucket for static assets
  2. Route to API Gateway v2 Proxy {proxy+} -> This passes through to the Remix Server housed in a lambda image
owlyowl commented 11 months ago

I am building a Remix Shopify app with SST. It is easy and very flexible. I love the experience. I have just used their drop-in mode after initializing the app using the CLI.

@JannikWempe Are you using lambda's at edge for defer?

codeyourwayup commented 10 months ago

This is a useful guide for setting up AWS for a Shopify web app.

owlyowl commented 10 months ago

We ended up having to remove API Gateway because it doesn't currently support lambda streaming (It will eventually).

So we've gone with a direct invoke streaming Lambda (can't wait until we can API Gateway again)

We wanted to use defer but it is pretty broken in Remix under React 18.2 where any 3rd party scripts or extensions that manipulate the DOM will cause it to hang and never resolve Promises properly. This unforunately was one of the bigger drawcards for using Remix so we've had to work around it and not get the benefits of Remix fully.

cypherpower commented 10 months ago

@owlyowl , do you have a public repository that we could use to begin working on this ourselves? I am working on deploying my own shopify app to AWS using CDK taking inspiration from https://github.com/rpg2014/remix-aws-cdk-template/tree/main

owlyowl commented 10 months ago

We use terraform and it's a private repo but I'd be happy to help.

Unfortunately with React 18.3 still not out we had to back out of using defer because there's no way we could put it in production.

We've also had to use concurrency because the lambda cold starts with the remix server and auth are really slow.

The fact that the remix template auths multiple times and redirects to the initial route a few times makes it quite slow at present. I hope they come up with a way to improve that.

On Sun, Jan 7, 2024, 6:06 AM cyphercon @.***> wrote:

@owlyowl https://github.com/owlyowl , do you have a public repository that we could use to begin working on this ourselves? I am working on deploying my own shopify app to AWS using CDK taking inspiration from https://github.com/rpg2014/remix-aws-cdk-template/tree/main

— Reply to this email directly, view it on GitHub https://github.com/Shopify/shopify-app-template-remix/issues/319#issuecomment-1879788916, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOT4CWBLEKNQ46KN5AXH43YNGOB5AVCNFSM6AAAAAA344VC5OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZZG44DQOJRGY . You are receiving this because you were mentioned.Message ID: @.***>

grosscoding commented 6 months ago

I am building a Remix Shopify app with SST. It is easy and very flexible. I love the experience. I have just used their drop-in mode after initializing the app using the CLI.

Have you managed to get it working with prisma session storage? For me it doesn't seem to work as it always tells the Session table does not exist...

JannikWempe commented 6 months ago

@grosscoding

Have you managed to get it working with prisma session storage? For me it doesn't seem to work as it always tells the Session table does not exist...

I am not using Prisma but I am using DynamoDBSessionStorage. It works fine for me.

In case it helps you or anybody else, this is the relevant code:

// inside SST stack
const gsiName = 'shop_index';
const sessionTable = new Table(stack, 'SessionTable', {
    fields: {
        id: 'string',
        shop: 'string',
    },
    primaryIndex: { partitionKey: 'id' },
    globalIndexes: {
        [gsiName]: {
            partitionKey: 'shop',
            projection: 'keys_only',
        },
    },
});

const site = new RemixSite(stack, 'Site', {
        // not relevant stuff omitted
    environment: {
        SESSION_TABLE_NAME: sessionTable.tableName,
        SESSION_SHOP_INDEX_NAME: gsiName,
    },
    bind: [
        sessionTable,
    ],
});
const shopify = shopifyApp({
    sessionStorage: new DynamoDBSessionStorage({
                // getEnvOrThrow is a only a helper for getting it from process.env
        sessionTableName: getEnvOrThrow('SESSION_TABLE_NAME'),
        shopIndexName: getEnvOrThrow('SESSION_SHOP_INDEX_NAME'),
    })
        // ...
})