I had a look at the angular way of doing it: very nice to see other approaches! From a quick look it does seem to require quite a bit more steps and to be more limited in scope, but the documentation looks very good indeed! Thanks for sharing!
Hi HN, this is our submission for PullPreview, a way to spin preview environments for any application directly from GitHub to cheap AWS Lightsail servers. No intermediary service involved.
## Context
PullPreview’s main use case is for making it easier to review code in branches or pull requests, because reviews with live code are always better than code-only reviews. This means better and faster feedback from reviewers (be it clients or teammates), so that everyone can iterate faster on the feature being developed.
However in most organizations, there is only a handful of staging servers available to the developers, which are hard to keep in sync, maintain, and with complicated processes to make sure you don’t step on someone else’s code.
PullPreview solves this with ephemeral environments for any pull request or branches, just by adding a label from the GitHub UI. URLs for the deployed environments are displayed right into the GitHub UI, thanks to the integration with the Deployments API.
## How it works (spoiler: no kubernetes)
Contrary to many other solutions, PullPreview _never sees your code_, because it runs as a GitHub Action and does all the work within the GitHub Action runner. The Action automatically provisions a server in _your_ AWS account (a cheap Lightsail instance), and then boots your application using the Docker Compose file(s) that you specify. The server is automatically destroyed when the PR is merged, closed, or the label removed.
Some of the features include unlimited parallel environments, support for SSH access, source IP filtering, port filtering, seed data support, data persistence across deploys, all managed from the GitHub UI.
All of this is packaged as an Open-Source GitHub Action that can be tried right now. You can run it for free for 30 days, and after that we have two license tiers at 120€/year and 300€/year. We believe it is pretty cheap compared to rolling and maintaining your own solution in-house. It is also free for non-profits.
## Next steps
We’re looking for feedback on the idea, what could be missing, and the pricing. We are also discovering many more use cases while dogfooding our own idea. For instance, we are currently running a few services in production, continuously deployed thanks to PullPreview (e.g. pullpreview.com itself).
First off, congrats on launching! I've personally been working on something very similar for the last bit, and actually plan on launching very soon.
As other commenters have mentioned, this is a system which seems all-to-common to have built in house, and I think you've highlighted issues with that: it may be simple to get something basic working, but without a larger investment, it ends up being unstable and unmaintained.
It's been great seeing all of the similar solutions being launched over the past month, and the slight different ways that different players (you, Okteto, LayerCI, Release, FeaturePeek, etc) are approaching this issue. I see that what you have done is specifically focused on Docker, and purposely avoided Kubernetes. I think that gives you a niche space, along with Dockup (https://getdockup.com/), who I believe are taking the same approach.
I appreciate your focus on security and privacy, specifically around "can never seen your code", but I'm curious about this choice. Did you find that this was actually a concern that customers had? CI/CD platforms, which are kind of a neighbor of Continous Product Review tools (this is how I've been referring to this class of product internally), and have an implicit trust. I have not received much push-back about automated code access, and when that has been a concern, I've found that those individuals preferred to how everything in-house anyways (Gitlab, or Github Enterprise).
Do you have any sort of cost-control structure in place? Being a Github Action, I see this more as a library than a managed service, which also means you have less control/ability to monitor your users ephemeral environments, and I would hate to see the shutdown behaviour break, and suddenly ephemeral environments never go away and your user is left with an obnoxiously large AWS bill.
Overall, I love what you're doing to approach this space in a new way. If you'd like to chat about the space, my email is in my profile (I literally just added it, so hopefully it's visible :fingers-crossed:)
Hello, thanks for your comment and the great points you’ve made.
Regarding security, we do believe that it is a selling point for many companies. You might be ok granting access to Circle CI or others, but for a new kid on the block that’s more difficult. And being run as a self contained action means you are not dependent on the availability or continuity of the service you depend on.
As for misbehaving instances, this is indeed something that we thought about, and we’ll make sure this doesn’t happen in two ways:
- allowing to set a max duration for an instance, and a max number of concurrent instances
- having an additional trigger in the workflow file to launch a cleanup phase like every day, since GitHub actions already support cron-like tasks
I’ll send you an email a bit later as I’m currently on the go, thanks again and talk to you soon!
> because reviews with live code are always better than code-only reviews.
Always? I don't know.
The author is responsible for testing and deploying the PR, not the reviewer. Also, in devops a lot of changes affect production, so cannot be fully tested until deployment.
It sounds useful for seeing UI changes, but the closer you get to the backend, the less visibility there is.
Or in companies with "political issues" like multiple groups with boundaries between development, test, and operations.
Maybe the PullReview people can add some use cases?
The idea here is not to skip the code review, but augment it with a way to experiment with the feature as early as possible in the development process.
It’s particularly useful for product owners who may not be coders and want to give feedback on how the feature aligns with the vision.
It’s also useful for other developers because seeing the thing live will give more context as to what the feature does and how it behaves, and as such might help reviewing the code and get reviews other than « good to merge » without any meaningful comments.
And finally it’s also very useful in making sure every dev can do a little QA on their feature in a standardised environment that runs with non-dev setting, without waiting for a staging server to be available.
The 80/20 rule most likely applies here. For some PRs you won’t need preview environments (just don’t add the label), but from my consulting gigs I have experienced more than once the need for this kind of tooling, and also witnessed more than once how many companies try to reinvent their own thing and the time they spend/waste doing so.
This looks pretty nice, though it seems this is a rapidly crowding space (although I didn't know there were any such tools until your post!).
Something I'm wondering about is how other cloud services fit into all this though - for example, messaging services, event streaming services, blob storage, table storage, databases etc?
Hello! The first recommendation would be to find a docker image providing a mock for the service you want (e.g. [1]) and if not enough then you could provision those services on demand in an additional step executing before the pullpreview step in the GitHub Action workflow file.
Also, something we didn’t mention on the site but might be interesting for some people: we’re more than happy to provide guidance and consulting on how to migrate your app to Docker Compose if that could be a blocker. Think of it as a kind of Concierge service. Don’t hesitate to send an email if you might be interested.
Interesting, I've never heard of the [1] "The Prosperity Public License 3.0.0", free for non-commercial use, or 30 days free for commercial use, which seems like a great compromise.
This idea is very similar to a few other solutions, [2] Release (YC W20), [3] Netlify Deploy Previews. However, this looks a little different, as it encapsulates everything into the repo's Github Action (except for the cloud provider setup). It also deletes the deploy once it's merged in, which Netlify's Deploy Preview's do not.
How does the domain name for the deployed website get provisioned? something like "pr222.myapp.com"
There are indeed a few other solutions to this problem. But we haven’t found any with all of the following characteristics:
a) doesn’t require access to your private code
b) works for any type of app
c) doesn’t require buying into kubernetes if you don’t want to
d) cheap to run
A little digression here but the main trigger for creating this was seeing a post [1] on the Basecamp blog about their implementation of preview envs for their upcoming service: It seemed so convoluted and expensive that surely there was a way to do it with less moving parts (I totally understand that Basecamp may require a complex setup like that, but I’m pretty sure it should remain an outlier).
Your comment about Netlify forgetting to remove the deployment link from the GitHub UI once it’s merged is also true, and from my testing Heroku also forgets to remove it. The GitHub deployment API documentation really needs some love, but still surprising since the removal is supported.
Regarding domain name provisioning, you can see a few examples in the demos linked from the features page. Currently the pattern is IP-gh-REPO_ID-[pr|branch]-[PR_NUMBER|BRANCH_NAME].my.pullpreview.com. Something I forgot to mention on the features page is that custom domain names are also supported. Custom patterns could also be supported without any issue.
> Since a new server is launched for every preview, it would be cool if the packaging used cloud-init vs docker-compose.
Actually the way it works now is that you keep the same server for the duration of a PR / branch. This means faster redeploys since the docker cache is there, and you don’t lose your demo data on every redeploy.
Cloud-init is used for the initial setup of docker and compose, but then the code sync happens through sending the app tarball from GitHub to the server and refreshing the compose.
We thought about mono-node k8s, but found that removing one abstraction layer would be better for now.
Yep, it’s also not limited to GitHub in any way and could be used straight from your dev machine or from other CI tools such as GitLab CI, Circle, Jenkins, etc.
I went with a similar idea of using Docker Compose to configure the app although with an extra layer on top of that to be able to expose multiple services. I wanted both the application itself and the ability to say, view the database using PGWeb while I interacted with it. You can see this in the screenshots in the link and I think this is quite a powerful feature as it allows you (in our case) to catch outgoing emails for example.
I never really got around to writing good documentation for standing up the service as it's quite complicated, but if anyone is interested I could help you through it.
Many companies have come with their own version of the concept, which in our experience doesn’t stand well the test of time (because the person that wrote the glue code left the company or docs are lacking or setup is very complex, etc). Hence PullPreview, so that companies can delegate the burden of maintaining that workflow to us, while retaining full control over their code and servers.
Our version is also Open Source (but not free except for non profits) and it doesn’t limit in any way the number of ports you can expose . By default and for ease of use ports 22, 80 and 1000-10000 are allowed in the firewall, but you can reduce that to the bare minimum with just a single config option. See https://github.com/pullpreview/action/wiki/Inputs For more details.
It's always interesting to see how others solve the curly edge cases too. I struggled with figuring out when to shut down a preview (hence why it deploys in an iFrame, I track presence using websockets and shut the preview down after the user is done)
Deploying on Lightsail is good too. I went with K8s and always had the intention of using some kind of VM level isolation, but (kind of) physically separate servers like Lightsail works well too.
Why thing I couldn't really figure out, how do you go with large docker images? The bulk of my spin up time is spent pulling the image. I never got around to figuring out how to do a good cache for it.
> The bulk of my spin up time is spent pulling the image. I never got around to figuring out how to do a good cache for it.
With our approach you keep the same instance for the duration of a PR or branch, so you mostly incur the docker tax On the first deploy. Afterwards it will reuse the local cache.
Yep, I suppose at $5 per month or whatever the cost of the instances, that's not actually a bad price. My assumption was to spread the cost of running the previews across a fleet, but like you said, you pay the docker tax :)
I developed something like this for my frontend team at a previous company as well. Much needed and I'm surprised not already mainstream. Love the focus on privacy/security.
I didn’t know about FeaturePeek, thanks for mentioning. It looks very similar indeed. From a quick look I would say the main differences are that it doesn’t run on servers you control, and is limited to frontend code only?
Also it’s pretty expensive with their per-seat pricing ;)
FeaturePeek cofounder here! Glad to see others in this space :-) Yes, our use case is mostly geared towards frontends devs getting design and product feedback from their team.
Right now we only spin up frontends (both pure static and Docker-based architectures, which you can of course point to backend services you host), and run in the public cloud (so not tied to your existing infra). By default, environments are private, so only the people you whitelist can access them.
On top of that, we overlay tools that let you comment w/ screenshots and screen recordings, and file tickets on third-party integrations.
We also have other neat usability wins, like each repo getting its own subdomain (rather than each pull request) so that you don't have to re-login to your app for each environment that spins up.
Hacker News is a funny thing. I see you made the same submission way earlier, and almost no reception. Now, it is exploding! Congratulations on that!
I am not going to hide that I am totally jealous, being a competitor to you (just in the managed and hosted space, instead of the on prem solution you offer), and launching my version of the same service as yours, Pull Dog (https://dogger.io) just a few days prior to this, with almost no reaction like your first submission.
That being said, I still can't help but think your project is exciting and share your excitement for this. I'll definitely be following the development as you evolve!
Hello, thanks for the kind words, and yes I think GitHub Actions have the potential to replace a large part of the current GitHub SaaS ecosystem.
There are a few demos listed in the Features section. The simplest one being a wordpress repo which shows the absolute minimal configuration required in terms of files (1 docker-compose, and 1 workflow file): https://github.com/pullpreview/demo-wordpress
You can clone that repo and fill in your AWS credentials in the Secrets section of the GitHub repository settings, and then you'll get a live environment running (like in https://github.com/pullpreview/demo-wordpress/deployments)
I would love to see a version of this for GCP an other cloud platforms (DO, Heroku, especially), would you be open to a collaboration there assuming I can code in your lingua franca?
Oh it's nice to see how well you've pivoted from PullReview! It's a great idea and I'll be trying it out shortly.. As a side note, @crohr was one of our first beta tester and paying customer of jidoteki.com (now on-premises.com), sadly their PullReview service didn't do as well as planned, but PullPreview seems to be a home run. I'm happy to see them building this service and look forward to watching the development.
I think you’re confusing me with the original creators of PullReview. My other venture is packager.io, which you might remember as well. Congrats to you for the continued development of your on premise packaging solution!
Ohhh Cyril haha you're right! Yes of course I remember packager.io. Sorry about that!! In any case, I still find this very interesting and will definitely check it out. Thanks for the heads-up.
I'm not familiar enough with the gaps between Github Actions and Docker compose to understand fully what this is doing.
I recall when I deployed my first docker-compose app it took less than 5 minutes (create droplet, login, git clone, copy in my secrets, docker-compose up)
I left that droplet running ($20/month) but if I wanted to tear it down regularly then it's a short script to do so.
Now - I'm pretty green on all this stuff and it was brain-dead simple even for me. What's the gap I'm missing that you're trying to fill?
It may be simple for you to do, but you just described having to provision a server, manually checkout your code using SSH agent forwarding or HTTPS auth, setup your environment variables, and then launch the app. And manually repeat the last steps as many times as you push to your branch.
At this point you’re the only one to know about your preview server, and you need to not forget to destroy it when you’re done.
PullPreview handles all of the synchronisation mechanism, as well as providing pretty URLs, automated SSH access to any GutHub users, source IP filtering, port firewalling, HTTPS support etc.
Plus the whole integration into GitHub so that you don’t need to retrieve the preview URL by yourself, and you get notified if anything goes wrong during the deploy, with full logs available.
It's really well documented and made the whole process a lot less work. It works great for angular apps.
There doesn't seem to be a ton of services in this space and for larger teams working on the same product I see this solving an actual problem.
Congrats on launching, excited to see where this goes.