Building a static serverless website using S3 and CloudFront
sanderknape.com
sanderknape.com
Another thing I really like, though I wouldn't really recommend it for corporate sites (but I would recommend it for personal sites because of the community/purpose) is Gitlab + Neocities. I use Gitlab CI to build my site, rclone to copy it to Neocities, and that's it.
Very simple, no-hassle combination with loads of bandwidth (I think my paid account has 3 TB/mo).
I've also had Russian users tell me that Netlify is sometimes blocked in Russia and can't access the sites but it may sporadic.
> No, netlify.com is probably not blocked in Russia. Yet.
> Details: > URL http://netlify.com
> Domain netlify.com
> IP 134.209.226.211
Is it intermittent?
Also, any idea why they would be blocked, or is that part of the problem?
https://isitblockedinrussia.com/?host=https%3A%2F%2Fwww.netl...
> Yes! It appears that https://www.netlify.com/ is currently blocked in Russia.
> Details:
> URL
> Domain
> www.netlify.com
> IP
> 167.99.137.12
> Decision 27-31-2018/Ид2971-18 made on 2018-04-16 by Генпрокуратура.
> This block affects IP 167.99.0.0/16.
My understanding is that the blocks are accidental side effects from the Great Telegram Blockage of 2018 [0] but I'm not entirely sure.
[0] https://en.wikipedia.org/wiki/Blocking_Telegram_in_Russia
We recently moved our static sites from S3+CloudFront to Netlify.
The S3+CF combination is clever, and very, very cheap. But it gets messy when you want to add things like custom headers and lots of redirect rules.
The full product can be compared to Google Firebase but the Amplify Console specifically offers features similar to Netlify on top of standard AWS services (S3/CF/Codebuild).
I find it a much better experience than manually setting up S3/CF websites because of the out-of-the-box features that simply wouldn't happen otherwise for a static site like:
- instant cache invalidation
- branch deployments (with password protection & rollbacks)
- deployment process only deploys modified files
- simple custom headers
- simple redirects (redirecting individual assets in Cloudfront is not easy)
At this point, there are a great many ways to skin a cat.
Assuming you've got $5 a month or so, it mostly comes down to personal preferences about workflow, vendor independence, security, reputation, and who you already have an account with.
There are many wordpress-like tools that spit out static files to upload to your hosting provider https://www.staticgen.com/
Maybe you want a static sites so that it'll 'live' forever and not be effected by future changes in software stacks. You definitely don't get that by doing this.
Maybe you want a static site so that it's simple to set up. It's not this.
Maybe you want a static site for security, all the complexity and accounts here make it less secure than a random site running random php.
This is just buzzword bingo for someone's resume.
Maybe the article overcomplicates but with services like Netlify, Amplify or Firebase Hosting it's stupid easy and cheap, and there's no vendor lock-in.
There’s only one account here (an AWS one), and since the content is public anyway there also isn’t much in the way of configuration subtleties.
If you have a way to compromise a static S3/CloudFront site more easily than you would a Wordpress instance that hasn’t been updated in 6 months, I’d love to read that blog post.
Buzzword bingo has unfortunately become a buzzword itself it seems.
You seem to have no idea what you're talking about. Are you claiming that a static site with Cloudfront and S3 is less secure than an arbitrary PHP website?
There are clearly tradeoffs. Running your own server on your own hardware in a colo or at home is the best option if you need it to run for 30+ years and don't want to worry about "software stacks". Good job, now you have to worry about hardware stacks and backups.
This solution has an instant, global CDN that mitigates low level DOS and provides better response time across the planet. But that doesn't seem important to you.
1. Buy the cheapest most unsustainable VPS ipv4 deal out there.
2. Make A record and WWW record and point domain to your new fangled server.
3. Configure server:
apt-get install nginx goaccess
cd website
cp * /var/www/html
Yearly maintenance required: apt-get update, apt-get upgrade
reboot
View traffic stats: goaccess -f /var/log/nginx/access.log
[...]
> Yearly maintenance required:
Well, presumably, find the new cheapest, most unsustainable VPS ipv4 deal, the previous one not having been sustained.
Also, the cheapest VPS you can find likely won't ever achieve the level of scale your static website in S3 could achieve. In the rare event you get a lot of web traffic, you're only hosed if AWS is hosed.
Also, i rather have my server go down than to receive a larger bill from aws, but that all depends on your use case obviously
The best part of S3 + Route53 is your costs are basically constant. $.50 a month for the hosted zone and then you pay pennies on the dollar for GBs of data transfer. In theory your bill could balloon if you had a hefty static website or some big files left public in your buckets and someone constantly downloaded it.
Usually you get what you pay for.
Sounds like you just made some bad choices. Big companies are only marginally less likely to disapear services than small companies are to disappear.
You've described my experience exactly.
I ask because actual servers seem like dark magic to me so I want to try to build a product with them, but I can't find anywhere if it's possible to run a reasonably secure server without years of studying.
Repeat above steps once vps provider goes out of business (as someone else also pointed out)
I'd advice against changing the ssh port - I don't think the (small) inconvenience is worth the (tiny) benefit to obscurity.
I would always recommend turning off password authentication for ssh, though.
(along with disabling direct root login via ssh, but root-with-key-only is now the default - and if you already enforce key based login, it's a bit hard to come up with a real-world scenario where requiring su/sudo is much help for such a simple setup).
I would probably amend your list to include unattended-upgrades (regular, automated security-related updates - but I guess that's starting to be standard, now?).
You will probably need an ssl cert, possibly from let's-encrypt.
At that point, with only sshd and nginx listening to the network - avenues of compromise would be kernel exploit (rare), sshd exploit (rare) or ngnix exploit (rare) - compromise via apt or let's-encrypt (should also be unlikely).
Now, if the site is dynamic, there's likely to be a few bugs in the application, and some kind of compromise seems more likely.
Do VPS providers offer some sort of similar firewall service outside your instance?
If you don't know that you'll be able to arrive from an IP or subnet - another option would be port knocking. (eg: knockd). Although, I'd try to avoid adding more code and logic to the mix - that goes for both fail2ban and knockd.
[1] ed: Note, the rationale for this is sound: the firewall (pf or nftables) is very good at filtering on IP - so better avoid introducing another layer of software that does the same thing.
To be honest I don't think the people controlling those bots want to deal with us that makes it harder for them to gain access. Instead why not happily hammer away everyone's else port 22 with the bare minimum configuration? Those who enhance the security were never the targeted audience to begin with.
This is pretty insightful. Statistically, attackers are probably mostly looking for badly configured machines which are easy to exploit rather than hardened systems that take a long time to penetrate.
State actors and obsessed attackers are different, of course. But statistically even taking care of using the simplest precautions keeps one out of the reach of the broad majority of such attacks.
My thinking is that even if I for example fail to sanitize inputs to a database or displayed to other users that won't lead to an exploit absent a bug in the off the shelf login module or someone attacking their colleagues (in which case there are other weaker links).
The organization I'm building this for has other moderately sensitive systems on an internal network, but the server I'll be managing will on the public internet. The site I'm building will export CSV files to be opened with Excel, so I suppose if the site I build was compromised it could be used to get an exploit onto a computer in the network. Still I presume if they're facing that kind of attack they'll have plenty of other weak links like documents spearphished to people and I'm pretty sure the sensitive systems are on a separate internal network.
Is my confidence crazy?
But I also think that I would trust eg apache/nginx basic auth, more than login/session handling at the application level (php/ruby/... with users in a db).
Assume at least one user has a dictionary password, and suddenly you'll want to enforce 2fa via otp or similar - for peace of mind.
As a general rule, I tend to assume a targeted attack will succeed (no reason to make that too easy, though) - what I aim to avoid are the bots.
They'll likely be brute forcing passwords, blindly trying sql injection - along with a few off the shelf exploits for various popular applications (eg: php forum software).
Hard disagree, even if for as simple a reason as port 22 gets inundated by drive by hacking attempts, making the log files virtually useless.
Running telnet with no password on any port would be, but having ssh on a non-default port isn't trying to achieve security through obscurity.
Write everything down! Every command you type. You don’t want to come back in sixth months time and have to relearn what you did the first time.
If you’re feeling ambitious you can script almost the entire deployment from provisioning a machine through to rsyncing the content. It’s pretty fun to run a bash script or two and see an entire server pop up.
I have Linux on my laptop and I've been trying to document what I configure with heavily commented bash code, but I've run into issues with editing config files. I frequently want to say something like "edit this variable to this value" but sed feels too fragile and easy to mess up silently, relacing the entire file is silently badly future incompatible if other entries in the config get changed in an update, and appending to the file so the last item overrides feels hacky and doesn't always work.
How does everyone else do that?
Have maintained enough servers for a lifetime, I’d rather be coding!
If you're running something dynamic like WordPress, stay extremely on top of patches, unfortunately, and be super cautious about what plugins you use. (This is one of the better reasons to use a static website.)
If you want to run a Postgres for your dynamic website, configure it to listen only to localhost or only via UNIX sockets.
Make sure you keep your software up-to-date. unattended-upgrades is a great idea for OS-provided software.
Be careful about where you get software from. More than just "get it from somewhere trustworthy," the big concern here is to get it from someone who is applying software updates. For most OS-ish things, you want to get them from your distro; try to avoid downloading e.g. PHP from some random website, because you won't get automatic updates. For a few things - especially things like WordPress - I wouldn't trust the distro to keep up, largely because the common practice is to release security fixes by releasing new versions, and distros are going to want to backport the fixes, which is slower and not always guaranteed to work.
As another commenter mentioned, turn off remote password logins and set up SSH keys. (Most VPS providers will have some form of console / emergency access if you lose access to your SSH keys.)
heaps of templates (because I'm often lazy), 1 stop shop for patches, locked down plugins (child sites can't install plugins, only enable/disable), and only one place to look for problems (& you can lock the wordpress site to a single IP if you always want to use it from a single place).
FWIW, I never groked AWS & it's ping times in my country are about 1/2 as good as local providers. (15-30ms for local, vs 50-100ms for AWS local). Speed matters.
Also, my use case is to 'fall over' (meaning: fail/stop working/be unresponsive) wrt DDOS, whereas I know many here are 'must not fail' (with varying levels of acceptability). So, I write concise, low bandwith consuming websites that appear instantly (to my local market users).
aws S3 cp $your-local-directory S3://your-bucket“Host a static website the HN way”
It would be overkill for a static website.
Gatekeeping alert!
Fortunately, there is more than one way to do things. I've been in HN for a while now and I don't do any of this. I was doing it when I wanted to learn, but now I need to get a project launched without any burden so I deploy it to ZEIT Now which is not the same as OP, but you get the idea.
I think this is key. If you have resources that are already serving things, the marginal cost of serving something else is low.
For a typical person not running servers for personal services, the upfront cost does not seem justified, when its so easy (and cheap) to setup and use the alternatives.
A true hacker way in 2020 would be using IPFS or Dat... =)
It's a great service, but I wouldn't count on it as your primary hosting.
https://www.slant.co/topics/2256/~best-static-website-hostin...
And as another comment mentions, GitHub Pages now offers HTTPS certificates [1] for custom domains, so GitHub Pages alone is sufficient for most static websites.
[1]: https://github.blog/2018-05-01-github-pages-custom-domains-h...
IMO the simplest solution for the OP is to have a private repository where he does any draft work, and then pushes the master branch (or whatever) to the public repo in order to "publish".
This option is available with or without a paid account, and I don't see any significantly better option available to paid accounts. The only thing you could do there is publish your pages from a private repo, and maintain your drafts in branches in the same repo. That is virtually identical to the original suggestion except that "master branch in public repo" is replaced by "master branch in private (same) repo" which probably makes little practical difference in the workflow.
It may look outdated, but it still functions well for me
One advantage is that they are auto renewing and you don’t have to manage them.
Could be bounces, but mostly just users who literally signed up clearly for my email list with 0 deception marking spam.
It's actually cut my content production down because I'm afraid to email. From 50 articles per year to 12 to 4 to 2.
Bounces also have their own system and should be handled by your email system as well.
And even at 4 a year I have this issue.
If 70 of the 7000 emails I send bounce or get marked as Spam, I get frozen until I ask for forgiveness.
Only costs ~$27/year to have a domain($15) and a static website deployed to S3/R53 ($1/month), which I've found to be fairly reasonable for the level of reliability I can expect.
I admit it is complicated up front but once it is setup and updates are automated it is really nice to not need to worry about self hosting, hardware, VPS', etc just for a simple website.
Or create an organisation on Github and publish this website as a Page. It is simple and it is free.
https://help.github.com/en/github/working-with-github-pages/...
Edit: I see others mentioned this too, but hopefully the link adds some added benefit!
I dislike the UX of AWS but the complexity here isn't strange to me. I bothered to set up the first bit of this (didn't need sub-dir index files so didn't realize it was a problem) since I wanted a simple storage, simple deploy and good resilience.
My site has been hit by HN a few times now and it hasn't been an issue. Fairly set and forget. But the start is annoying.
Their business is making big complicated things possible for companies that are going to spend a lot of money and don't care about a small amount of incidental complexity.
While imposing technical limitations to extract more revenue along the way.
My non-technical employees and partners like Wordpress. We like the plugins that make web development easy and not arcane.
But we don't like the fact that every page requires basically a database read. Yes, we use WP-SuperCache, and it's ok.
But why oh why is it so hard to do the editing on Wordpress and the publishing on a Static site? Anyone with some real guidance here?
We want the people who come to the site to get the static experience while the people who edit the site to get the Wordpress experience.
You can either do this explicitly using a small scraper tool, or implicitly using aggressive reverse-proxy caching rules.
Maybe you’re doing something more complicated that isn’t amenable to pseudo-static?
Oh I'm sure it is. Static website is just that--static. You don't have a database, and that is a great thing, but that also means you can't store stuff like users, comments, articles to be published in the future, etc. out of the box.
You can do all of that of course, but it's going to be difficult, and you're gonna plug non-static parts to your static website (such as plugging the comments part). All in all, you can't expect to have all the advantages of static websites as well as Wordpress.
I personally simply took my content from Wordpress and built a new website with gatsbyjs. It's fast, clean, and entirely in React + Typescript. It has no dynamic parts, though. If you're a business and your Wordpress site is production critical, who knows, you might not want to migrate. You might also want to explore alternative solutions, like split some parts of your Wordpress blob into several static websites, and keep the main WP site with less content that's easier to manage... There are a number of possibilities.
In theory, wordpress doesn’t even know it’s happening. Make sure to disable any caching plugins as well, you won’t need them anymore.
I set up such a system for my old research group during my PhD (as they were not allowed to use Wordpress directly) and they are still using it 8 years later: http://iramis.cea.fr/spec/Pres/Quantro/static/index.html
Back then I wrote a simple Wordpress plugin that would create an empty file when a button was pressed in the UI, and I had a cron job that was executed once per minute, checked if the file existed and if so deleted it and copied the new version of the dynamic website to the static server.
2 - You can run a process to crawl your WP site and output all the pages as static files, then upload those for hosting. WP2Static handles that for you: https://wordpress.org/plugins/static-html-output-plugin/
3 - Use Wordpress as a "headless" CMS for editing and storing content, then use one of the modern static site frameworks to get content over JSON/HTTP from Wordpress while building your site.
I'd go for option 1 and call it done.
[1] https://wordpress.org/plugins/static-html-output-plugin/
Use what works for your teams. Apparently, that's Wordpress and that's okay.
> We want the people who come to the site to get the static experience while the people who edit the site to get the Wordpress experience.
Stick a caching proxy or CDN in front of it, not just a Wordpress cache plugin. Something like CloudFlare would help you out.
The Lambda@Edge functions especially. They have 4 phases they can be injected into: viewer-request, origin-request, origin-response, and viewer-response. If you put your code in the wrong place you get hard to debug issues. Additionally you cannot “annotate” a request, so a decision at say “viewer-request” cannot pass information to later stages.
Also, deployments take 15 minutes at least which just further frustrates the debugging process.
I know, I know. For developers it beats obtaining permission every time you want to spend $5/mo on some plumbing and for managers it beats getting fired because you chose Google cloud and they canceled it the next year. Still... ugh.
https://gitlab.com/verbose-equals-true/django-postgres-vue-g...
and here's how I deploy that site with GitLab CI.
https://gitlab.com/verbose-equals-true/django-postgres-vue-g...
Also, nobody mentioned GitLab pages which offers some pretty nice static site solutions as well.
If your CFN gives you headaches ever, maybe take a look
> GitHub Pages is available in public repositories with GitHub Free, and in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server. For more information, see "GitHub's products."
Earlier today I modified the popular jakejarvis s3 sync github action to allow for this during my CI/CD process.
Relative pathing can be useful depending on file structure.
It avoids issues with directory / page naming conflicts. E.g. my images are stored at /assets/img/image.png - but if I wanted to create a page at example.com/assets this would require me to then place an index.html inside my assets directory - which doesn't seem logical.
Overall, mostly personal preference of me disliking the index.html inside directory method - It just doesn't seem like it's the "right" way to access a page. If I have a example.com/about page - I expect them to be hitting an about.html file.
const streamsBucket = new s3.Bucket(this, 'StreamsBucket', { websiteIndexDocument: 'index.html', removalPolicy: RemovalPolicy.DESTROY })
/* Create a cloudfront endpoint to make it publicly accessible */
const streamsDistributionOai = new cloudfront.OriginAccessIdentity(this, 'StreamsBucketOAI', {});
const streamsDistribution = new cloudfront.CloudFrontWebDistribution(this, 'StreamsDistribution', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: streamsBucket,
originAccessIdentity: streamsDistributionOai,
},
behaviors: [ {isDefaultBehavior: true} ],
}
]
});
Will create a bucket that will serve index.html from a non website bucket. Three lines of cdk code. If you need to populate the bucket, add another line to create a new BucketDeployment to populate the bucket.All files are secured by OAI and not accessible over the public internet.
Sure, S3 works if you're deploying it as safest as possible and want to pay for it too and do this on a recurrent basis, but otherwise is too big of a fuss for a personal blog, I use GitHub pages for over 4 years now with no issues, my own domain and SSL.
The simplest is surge.sh, period. If you don't need a domain, a web platform and just want to deploy from your CLI, surge.sh is the solution. It's good when you want to show off a static website to someone outside your sever. Even the switching to a premium plan is done from the CLI.
Other solutions are: Netlify, ZEIT Now, Aerobatic or Render.
I frequently use this list from this GatsbyJS wiki to check for static website hosts, I recommend it: https://www.gatsbyjs.org/docs/deploying-and-hosting/
“However, the S3 website endpoint is publicly available. Anyone who knows this endpoint can therefore also request your content while bypassing CloudFront. If both URLs are crawled by Google, you risk getting a penalty for duplicate content.”
I’m curious if anyone has experienced these issues in practice.
I assume that's the reason for really wanting index redirect in directories. Pretty URLs, I didn't feel the need. There are other valid reasons too I'm sure. But my needs diverged from the article even earlier than SEO penalties.
https://docs.aws.amazon.com/AmazonS3/latest/dev/HowDoIWebsit... https://docs.aws.amazon.com/AmazonS3/latest/dev/IndexDocumen...
I put up a Jekyll site on s3/cloudfront recently and it seems to work well.
Anyway, I’m still wondering about the consequences of the naked s3 endpoint being available.
I use a digitalocean instance where I install nginx. Then I copy the static files through sftp or scp. For ssl, I install letsencrypt.
No React.
No Vue.
No Ember.
He just sat there.
Writing HTML.
Like a Psychopath."
(credit to https://twitter.com/kiddbubu/status/1187120868259979269)
FYI starting with 0.63.0 the speed has about doubled:
BTW: I just moved it to Netlify since reading this thread. Took me ~5 minutes.
[1] https://github.com/HeinrichHartmann/HeinrichHartmann.github....
Thanks for the very valid counterpoint!
The post here is using Lambda@Edge to handle pointing example.com/about/ to example.com/about/index.html
However there's a lot more you can do / may want to do with Lambda@Edge if you're hosting a Cloudfront+S3 website.
I just wrote up how I set up a system to make managing server-side redirects (e.g. 301s from /old-page to /new-page) easier via Lambda@Edge.
https://news.ycombinator.com/item?id=22351484
https://engineering.close.com/posts/redirects-using-cloudfro...
https://dev.to/jillesvangurp/using-cloudfront-s3-and-route-5...
IMHO, Amazon should be ashamed of themselves for making it so unbelievably convoluted and hard to host a simple website on cloudfront. It's the one thing almost every website out there has to solve and they made it super painful to get this right.
I also wrote follow up posts on adding document search: https://ethanaa.com/blog/document-search-with-algolia/
And continuous deployment: https://ethanaa.com/blog/continuous-deployment-with-circleci...
1. Add your domain in AWS Route 53
2. Tell it which git repo & branch you want to use (including private github ones)
3. It detects the repo contains a hugo site (works for other ssg) and generates a build script
So now every time I commit to my selected branch, Lambda is notified, it fires up a vm to generate the html, move it into S3 and takes care of Cloudfront, SSL & so on.
Also, while I’m at it, static websites are, in my opinion, a little “gimmicky” since it’s impossible to determine the user’s browser size at build time. This means that you have to make a choice to build for either mobile or desktop first. Then, if the user is using the other device, they’ll encounter the FOUC issue (flash of unstyled content).
For me, that’s big enough reason to not use static websites in the future.
A normal CSS file is render blocking so the DOM content won't be displayed until the browser has downloaded it, parsed it, and knows what to display. If you move your main layout styles out of the component (presumably this is using styled components or similar?) and in to a CSS file that's defined as a <link> in the header of the page then that problem will go away (or a <style> tag in the header if you're worried about the additional fetch). This is how browsers have been designed to work.
Personally I just listen for any event and invalidate all objects, since that's way cheaper than issuing an invalidation request for each object, but performance wise that might not be the best option.
https://gitlab.com/bitemyapp/statically-yours
There's a weird bug with the `tf init` but it can be worked around by running `tf init`, deleting the providers in `.terraform`, then running again. Hashicorp has an open bug for the problem I think.
I could probably clean it up more but this has been okay for a couple sites I run.
For example, say you want a single index.html file, with each article contained in a separate content file - "blogpost01.html", "blogpost02.html", etc. - that you somehow include in the <body></body> of your index file?
Is there any way to do that with a static site, or something similar where your content is separated out into individual files?
We've run into two things though:
- We have very little control over TLS versions and cipher settings.
- We have to use a CNAME so we can't point a bare domain at it which also means we can't add our site to the HSTS preload list (I think there is a way to purchase an IP though now, if anyone knows please let me know).
Overall totally worth it though.
Say my regular bill for this setup was $5 a month. Can I at least get a notification if I have a lot of visits and the bill goes over a threshold, say $50?
Also, is there any protection against things like DDoS that could quickly push the bill into the $100s and beyond?
What you do in response to such an event is entirely up to you
The way the API has been designed to make the usage natural/guessable has inspired me a lot when I have made other CLI projects.
With things like Cloud Run that can run a container on-demand for every request, it's easier to just stick with regular Wordpress or Ghost server-side stacks.
Not for my blog.
If you're editing markdown files with only text and running a simple convert to html then it'll work fine, but ghost/WP in a container would work just as well.
People will bounce back. It will take far too long to load. The point of a static site on a CDN is speed. If your goal is to get outside visitors, then you definitely do not want to do this.
I can understand Cloud Run for demoing small apps though.
Frameworks like Nextjs Static Site export and Gatsbyjs have a lot of tooling support for firebase hosting and netlify.
Well, I do that, so I guess I'll chime in.
First and foremost is the idea of not tying your site's build process and hosting to a company that could go under. Yes, Amazon could, but if I had to bet Netlify will either cease to exist, be bought out, have its free offering discontinued/changed/etc. long before that.
Second is that sometimes your site's build process is more complicated than what Netlify provides. For example, my site is a static Hugo site, which Netlify supports, but there's one crucial step in the build process where I turn my "resume.html" page into "resume.pdf" -- I have to run a Docker image that starts headless Chrome in order to render the PDF properly. As far as I can tell, that can't be rigged up in Netlify.
Finally, I was able to learn a lot about AWS by hosting my site this way -- setting up a Lambda to listen for GitHub commits, using the AWS API to launch an EC2 instance to build my site, how to configure S3 and CloudFront to serve up content properly, etc. And at the end of the day I get a site that I have complete control over and is approximately free to run.
For the PDF, there's probably some service that could be used to wire that quick. But I agree that can be the cut-off point where it might be simpler for some to use docker.
Sounds like you're imposing a complex build process on yourself while getting locked into a web of AWS features to be honest.
Could you not skip generating the PDF resume since you've already got the HTML version to keep life simple?
If you stick to running a basic NPM script to build your site there's little lock-in with Netlify. You could also build your site on a CI platform then push the generated pages + assets to Netlify after.
I should elaborate a little. My whole site is contained within a Docker container that has NPM, Yarn, headless-chrome, Hugo, etc. I can generate everything with a single command. The AWS bits are just there for hosting and responding to a GitHub commit. So the build process is portable-ish, but from what I saw Netlify doesn’t just let you do headless-chrome on a free plan[1].
> Could you not skip generating the PDF resume
Not really, the point is to automate everything away behind a single Git push.
1: https://community.netlify.com/t/using-zipped-binaries-how-to...
To be fair, when you dive deep into complexity, it's easy to get lost in the weeds. The trick is to remember what you're doing and why you're doing it so you don't lose sight of goals while chopping through the complexity jungle.
we get all that for free now or 50 cents a month, just for static websites
there is almost no comparison, except for acknowledging that the plumbing sucks, all of which you can make better if you want.
Since when? I thought most people liked the simplicity and low barrier to entry…
SSH/SFTP helped a lot on the security front, but even for small companies, it's way easier to use cloud buckets than FTP.