-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ci): use Depot for Docker builds in CI #10002
Conversation
|
||
- name: Login to DockerHub | ||
if: github.repository == 'PostHog/posthog' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole workflow is already guarded with if: github.repository == 'PostHog/posthog'
, so I've removed the if
s from individual steps.
@@ -10,6 +10,7 @@ on: | |||
jobs: | |||
build-push: | |||
name: Build & push Docker release image | |||
if: github.repository == 'PostHog/posthog' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this one, it was missing the if
guard for the whole workflow like some of the others, so I've added it to match, though let me know if this was in error and I can revert.
depot.json
Outdated
@@ -0,0 +1 @@ | |||
{"id":"x19jffd9zf"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the ID of your Depot project in the PostHog org - Kyle has sent @timgl an invite to the org, and he can invite anyone else who needs access 👍
with: | ||
push: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
push: false
is the default (for both Depot's and Docker's build-push-action
)
Thanks @jacobwgillespie! I have added the secret token. @fuziontech any thoughts/feedback? |
I think we might have a workflow issue to solve first - workflows triggered via I think we have two options:
I think (2) is preferable, let me sync with Kyle on that idea, and definitely let me know if you have thoughts as well. (and thanks for your patience, this is our first OSS project integration) |
Alright, we have implemented option (2), we now support acquiring temporary Depot build tokens by exchanging GitHub Actions OIDC tokens, assuming they match the project trust relationship configuration. 🎉 I've created a new And we've released a new version of This should be good to re-test. 👍 If this works and we like the approach, we could update the other workflows to use OIDC, then you'd have one less static API token to manage. 🧹 |
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, post a comment or remove the |
I've updated the branch with the latest from The Docker image build job failed with |
Alright, well it appears OIDC does not work with I've pushed a commit to revert the I've also pushed a commit to use OIDC on all the other workflows, there's no reason you should need to embed a static access token anymore. I'll add a comment on one bit of Actions code below. |
with: | ||
context: . | ||
file: prod.web.Dockerfile | ||
load: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, this change reflects the previous behavior, ordering the steps like so:
- Build the image, loading the result in local Docker
- Push the image to ECR
- Extract static assets by copying out of the built container
With Depot, I think it would be faster to reorder it such that the image it pushed to ECR during build (via the remote builder), then pulled locally for asset extraction:
- Build the image and push to ECR from the remote builder
docker pull
the image from ECR- Extract static assets by copying out of the built container
That would add some additional network transfer costs, since you'd be pulling the container from ECR, if that's a concern, hence why I did not make that change. There might also be a way to extract and push the static assets as part of the Docker build itself, to avoid needing to pull the container again at all.
@@ -0,0 +1 @@ | |||
{ "id": "x19jffd9zf" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some non-blocking (tiny) feedback, I'm always annoyed when a service forces us to add a file with their name into our main repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally understand, I feel the same! I've started using VS Code's file nesting feature just to hide those files I can't remove from the repo root. 🙂
We support three ways of getting the project ID to depot
:
- The
depot.json
file with anid
key - A
DEPOT_PROJECT_ID
environment variable - Passing it as a CLI option:
depot --project xxxxxx ...
The benefit to (1) is mostly that the CLI will find that file up from the current directory, so you can cd
into the project, run depot
and everything works with no additional config.
But if Depot is mostly useful in CI and/or you have some other way of providing env vars in your local shell (direnv, etc.), we could drop the config file for specifying it that way instead, it'd save one additional file in your repo root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'd prefer either env variable or CLI I think!
Again not blocking though. Just getting a final look from someone in our platform team but then we're good to merge. Thanks for your work here!
Interesting, it failed to find the project token - let me take a look... |
…10002)" (PostHog#10179)" This reverts commit efb1eb2.
(context for this is an email exchange with @timgl, who requested this PR)
Problem / Background
Faster Docker builds!
When building Docker images in GitHub Actions, the lack of a native Docker build cache means builds can be quite slow, and even options like
cache-to
/cache-from
can eat into build time since they must serialize / deserialize the cache to tarballs which comes at a performance cost. And Actions currently only offers hosted Intel environments, if you need to build Arm images, you need to use emulation/QEMU, which can be slow.Depot is a hosted Docker build service that we've created to make this faster - we spawn managed VMs running BuildKit on-demand to handle container builds. Those VMs have 4 CPUs (2 more than Actions today), 8GB of memory, and a persistent 50GB local SSD disk. This allows all of BuildKit's native cache features to just work and persist across builds. Our builders start in just a few seconds with the SSD disk already ready, no need to load the cache before the build can start.
We have a CLI,
depot build
, that embeds a copy ofdocker buildx build
that routes builds to our infrastructure. Since it's using Buildx as a library, it's typically just a matter of swappingdocker build
fordepot build
to send builds to the remote builders.We've been benchmarking several open-source projects in GitHub Actions that you can find on our homepage, and PostHog is one of them. Every commit to
master
here, we've been running adocker/build-push-action
job and adepot build
job and saving the timings. We've been seeing build times with Depot of <5 minutes, often around 2.5 minutes, and sometimes as fast as 20 seconds!@kylegalbraith reached out to Tim to see if you all might be interested in those speedups here in this repo, Tim asked for a PR, and here we are 🙂
Changes
To use Depot here, I've made the following changes:
depot/setup-action
docker/build-push-action
is replaced withdepot/build-push-action
, which implements the same inputs but executesdepot build
instead ofdocker buildx build
depot.json
file with an ID - this is the ID of your project, an abstraction around a builder VM and cache diskDEPOT_TOKEN
secret - this secret does not yet exist, you will have to generate it and save it here (I'll ping Tim about this via email too)I'll add a few code comments below for some other minor details.
The tl;dr for how all this works:
docker/setup-buildx-action
launched a local copy of Buildx, anddocker/build-push-action
used thedocker buildx build
CLI to interact with it to build imagesdepot/setup-action
installs the Depot CLI, called bydepot/build-push-action
, which embeds thedocker buildx build
client to tunnel to a remote builder VM that's launched on demand, with a persistent SSD cacheIf you have any questions, feel free to ping me (@jacobwgillespie) or Kyle (@kylegalbraith), we'd be happy to help in any way!
👉 Stay up-to-date with PostHog coding conventions for a smoother review.
How did you test this code?
Yes I've run
depot build .
locally against this project ID. I have not yet tested these specific workflows as they don't execute for repo forks, and theDEPOT_TOKEN
secret doesn't exist yet in this repo.