[StaticSite - Potential Bug]: Ever since the remov...
# sst
d
[StaticSite - Potential Bug]: Ever since the removal of the atomic deploys… it no longer seems to handle orphan files (deleting/removing old files from s3) Below is a screenshot of our production bucket with a file last uploaded on Feb23 which we’ve since removed from the frontend code (thus should not be in the bucket) and redeployed. What is “supposed” to happen with orphan files? We are on
SST v0.60.2
@thdxr @Frank Any idea if this is a “thing” or if it was fixed in a more recent version?
This is currently a production issue for us. 😨
d
I believe that this was the tradeoff
@Frank Anything we can do here to either: 1. empty bucket before deploy each time 2. merge uploads and delete orphans
the current solution breaks our production pipelines. In that our site is exposing old pages that have been deleted.
f
Yeah, let me add the ability to clean up old files.
@Dan Van Brunt can you give this beta release a try
0.66.4-next.2
I added a
removeOldFiles
flag to
StaticSite
(default to
true
). So I don’t think u need to change ur code, the default behavior will be removing old files.
d
SO MUCH THANKS 🙏!!
Will try today
Out of curiosity, how are you going about this? Emptying bucket or just targeting orphans with some kinda sync?
f
The latter.
Emptying bucket could cause intermittent down time
d
Perfect! Def going to look at that code. Was wondering how that could be done to mimic
aws s3 sync -d
f
it actually can’t be done with
aws s3 sync --delete
given how
StaticSite
is grouping files into multiple zips to get around Lambda’s 500MB disk space limit
StaticSite
now creates a file with all the file names, then at deploy time gets all the files in the bucket, cross check with the file names, and removes the ones that no long exists.
Pretty much what
aws s3 sync --delete
does behind the scene.
d
Wow, great! Thanks again.
@Frank I think we’re doing something wrong or perhaps the next version has other things in it?
stuck at the moment on this.
t
Ah we renamed ApolloApi to GraphQLApi
d
ah…. kk… and the first error there? @thdxr
t
first one is a warning we should fix
d
I think its because your packaging is putting the package.json into the dist folder and should not be?
t
yeah I'm not sure why that's going in there
d
I think this could cause intermittent downtime even with the targetting of only old files for the same reason as before, if someone is on a page and that page is referencing a static file of the old deployment, you would have to refresh the page to get it working again.
It’s almost like the ideal would be to keep two deployments, and delete older than two.
d
@Derek Kershner yup… I think the key here is that this type of deploy is NOT trying to solve the atomic deploy problem.
d
then it probably shouldnt be default.
d
Well that is likely the key question based on the face the atomic deploy USED to be the default
d
or just that a default shouldnt cause downtime
d
but in that line of thinking… what should/could have been done is to make the old atomic deploys way the default and make this NEW way of merging/deleting the option.
@Derek Kershner That is not possible. The “default” was atomic deploys… and they DO cause “extra time” / not down time.
I was not aware that the old atomic deploys cause downtime…. I though it was a straight swap from one distro bucket key to another instantly.
its just that it took time to replicate.
d
its more the client getting “stuck” on the old deploy. Cft + S3 are able to be seamless, but the browser can ask for whatever it wants.
d
sure…. but there is no way around that even in using a server…. best you can do is keep v1 and v2 public while all the active user sessions are moved to v2
d
…other than having the previous deploys files present, which was Frank’s idea behind the move.
d
which I think would be way out of scope for these constructs (and should be)
d
I’m good with whatever, as in the other thread, just making sure that we arent doing a double tradeoff and throwing a baby out with some bathwater.
d
Doesnt seem that this would work anyway… https://serverless-stack.slack.com/archives/C01HQQVC8TH/p1646326499650809?thread_ts=1646235250.400579&cid=C01HQQVC8TH There are going to be FILE NAME/PATH that do NOT change but their CONTENT does (index.html)… that would cause this solution to break.
d
lol, always odd having the same argument representing the opposite opinion as before, but basically you have: • Files where names stay the same (index.html). These can change and the request will get the new one. • Files where the names are NEVER the same (
static-deploy1234.js
). These ones will be requested based on whatever the client currently has open, and cause the downtime if deleted.
Frank can weigh in, its possible he is being more targeted than it sounds.
t
I think we confused atomic deploys with being able to support an environment per commit (eventually). The old approach was built to support the latter The new approach was simplified giving up the latter because you can already do per stage environments BOTH approaches should still support atomic deploys in that nothing should break during a deploy. So we shouldn't give up atomic deploys (by default at least)
So the new flag Frank added works if people are OK with breaking their previous deploy but should probably be false by default
d
@Derek Kershner Not sure I follow, but it seems as though there are some key truths in all this: 1. There is no comprehensive way to setup atomic deploys that allow for users to see v1 and v2 and use the site without error unless you make their session sticky to v1 / v2 2. The previous (with deployId) method was the closest thing to a clean cutover but would not handle session edge-cases above 3. The default method for StaticSite could either be ◦ what it was all this time with deployID ◦ simply try to solve the issue of speedy deploys and clean accurate deploys (no orphan files) which is what Frank is talking about putting in above 4. Those that want #1 above would have to handle that outside of this construct as it would need deployment cutover handling for sticky sessions.
d
All I was here to do is point out two conflicting tactics, and make sure a bug fix doesn’t defeat the point of a previous tactic change, lol.
Those that want #1 above would have to handle that outside of this construct as it would need deployment cutover handling for sticky sessions.
This was actually Frank’s reason for the tactic-switch on this construct in the first place, but with
framework-specific knowledge
in place of
sticky sessions
. And, as before, I am still good with it and like the direction for the framework specific constructs. I just have an absolutely critical static site that needs to be 100% available (just a few files, no real framework), so I need to watch this default closely if it switches to breaking the deployment.
d
To be fair… isn’t “changing” the default to have orphan files not going to fix anything. There are still going to be scenarios that require some part of experience to be locked to v1 or v2. A simple v2 API change would also cause the errors with a user in a v1 session. Not to mention that deleted routes should stay deleted. I don’t think its a good compromise to allow stale sessions to use old routes if they’ve been removed….. chances are they NEED to be removed. Especially when considering more sensitive content like we have in Pharma.
d
I am also not questioning that this is a bug, if I have done this somewhere, it was a mistake.
d
I’m also super happy so long as there is an option to clean up orphan files, regardless if its the default. But I am trying to debate so that the decision on the default makes the most sense. Since, we’ve already just changed it once.
Also …. I’m super late to the party since I know you guys beat this horse dead already it seems in another thread 😄
d
very dead.
I am not sure that there is really another choice, but I am just pointing out that this crushes Frank’s dreams of seamless.
And I also just realized that this doesn’t actually affect our use case, since we aren’t using any deployment-specific files.
I think you have to know the framework to do better, I have switched my opinion to leaving this alone with the default
true
. Fight the battle in the specific frameworks.
d
What are you referring to with “know the framework” and “Fight the battle in the specific frameworks”? I think that is from previous convos I missed?
d
Yes. You can have the best of all worlds if you know things, this is Frank’s aspiration, but not with this construct.
d
not sure what “framework” that refers to though.
d
CRA, Vite, NextJs, etc
d
ah
Anyway… @Frank sorry for opening up this wound again. But we need a prod fix for the orphan files and my vote is to make removing them the default, as it is was for us on various plugins when we were using SLS. BUT happy to just get a fix regardless 😄
@Frank @thdxr Seems like it’s not working? https://serverless-stack.slack.com/archives/C01HQQVC8TH/p1646311028485579?thread_ts=1646235250.400579&cid=C01HQQVC8TH I just deployed twice, once with an “about/index.html” and next with that file removed from the frontend. • confirmed in
.build/
that the staticSite package showed that file removed • confirmed that file WAS in the s3 bucket before deploy • confirmed that file was STILL there after deploy that should have removed it. • As I understand its true by default, I made NO changes to my StaticSite props.
Copy code
"@serverless-stack/cli": "0.66.4-next.2",
    "@serverless-stack/resources": "0.66.4-next.2",
f
@Dan Van Brunt aight let’s sort this out. By deploy, u mean
sst deploy
not
sst start
right?
First check
Go into
.build
and look for a folder called
StaticSite-xxxxxx-xxxxxxxxxx
. Do u see a file named
filenames
? Open it up and see if
about/index.html
is in there. (This file is what the Custom Resource will look at and remove all files in the S3 bucket that are not listed in this file.)
about/index.html
should NOT be listed in
filenames
.
Second check
If first check passes, go to CFN console, find this stack, and go to the
Template
tab. Search for
Custom::SSTBucketDeployment
and can you paste the resource here? It should have a
Filenames
property.
Let’s do this 2 checks first.
^^ yeah after discussing w/ @Derek Kershner, we decided to keep
StaticSite
simple and not do too much magic around deployment. We will tackle how a site is deployed in a framework specific way. For example, for CRA apps, u’d want to override
index.html
and keep
static
assets around. So for users that have the old
index.html
open, all the js/css files are still reachable. Next.js apps work in a similar way. And to get fancy, we can generate a unique url for each deploy, similar to what Netlify does.
d
@Dan Van Brunt, you ever get this figured out? I am running into the same issue in 0.68.0.
d
@Derek Kershner Ya, @Frank gave me an alpha to test, but I was unable to get that version to correct the issue…. then hand to jump on something else before diving after what might be the delta.
d
are you just manually deleting files in the meantime?
d
I’m just not worrying about it atm since our ONLY SST implementation is yet to go to production.
If this one is a success… we’re likely to switch everything over to SST
d
i just realized this affects all of the static site types…not just the base one.
its less pronounced in the SPAs, since they have a single HTML file, though.
f
Hey guys, sorry for the late follow up. Was caught up w/ a upcoming release.
@Derek Kershner have you had a chance to try out
0.66.4-next.2
? A
removeOldFiles
flag was added to
StaticSite
(default to
true
).
d
@Frank, I am wondering if perhaps a better way to handle this is using the
FileListOptions
(that is from memory, not exact) props to manage whether certain file patterns get deleted. That way it could be extended to deleting some, but keeping others, like you want to do in the other StaticSites.
I haven’t tried that option, though, I built my construct based on 0.68.0, and not sure I could go back or not.
f
yeah good point. Can you share an example what
FileListOptions
woudl look like?
d
current:
Copy code
export interface StaticSiteFileOption {
  readonly exclude: string | string[];
  readonly include: string | string[];
  readonly cacheControl: string;
}
new:
Copy code
export interface StaticSiteFileOption {
  readonly exclude: string | string[];
  readonly include: string | string[];
  readonly cacheControl: string;
  readonly removeOldFiles?: boolean;
}
you could make it default to true if you wanted to handle the base, non-specified files that way
also, ticket: StaticSite (all types) - Deleted files do not get deleted (and are therefore still available on S3/urls) · Issue #1513 · serverless-stack/serverless-stack (github.com)
f
Yup, let me try out this concept today and follow up here.
d
@Frank If its helpful, we can test again, we’re still on version 0.60.2
f
Hey @Dan Van Brunt yeah it’d be great if u can give it a try again. I wasn’t able to reproduce the isssue on my end.
If still no luck, can u do 2 quick checks:
First check
Go into
.build
and look for a folder called
StaticSite-xxxxxx-xxxxxxxxxx
. Do u see a file named
filenames
? Open it up and see if
about/index.html
is in there. (This file is what the Custom Resource will look at and remove all files in the S3 bucket that are not listed in this file.)
about/index.html
should NOT be listed in
filenames
. (edited)
Second check
If first check passes, go to CFN console, find this stack, and go to the
Template
tab. Search for
Custom::SSTBucketDeployment
and can you paste the resource here? It should have a
Filenames
property.
d
still the same version?
0.66.4-next.2
f
yup
d
kk
trying now
@Frank I don’t see this as a tag, branch or anywhere in the repo
0.66.4-next.2
f
It’s in the feature-static-site-purge branch. This commit has all the changes https://github.com/serverless-stack/serverless-stack/commit/328767dde083f728cc6eafcf5740d99dc3315594
d
@Frank Works! Pretty sure I know what the issue was. I missed one of the yarn links I needed. sst.resources > klick.packages > projectX
Do you need any more testing before I move back to my other work? Any idea when this fix could make it into a release?
f
I will release it today.
@Derek Kershner I haven't gotten a chance to think through ur proposal. lemme create an issue for now. If it becomes a blocker for u, lemme know and I will pump up the priority.
d
I only use
NextjsStaticSite
and the extra files dont cause issues for me, other than storage, because the
CloudfrontFunction
will still return a 404 on its own, even if the file is there.
Anything else I do is covered by this fix.
f
@Dan Van Brunt @Derek Kershner Released in v0.69.1. Renamed the option to
purgeFiles
, default to
true
.
d
THANKS! will give this a go tonight! Thanks!