In this chapter, we are going to explore E2B sandboxes. This will be the environments where our AI will generate files and create a working Next.js application. In this chapter, our specific goal is to create an E2B account, learn how to use their command line interface, and create a Dockerfile template for our Next.js project, and then push that template to E2B. And then we're going to preview that Next.js application inside a sandbox. So we're not going to make AI create any new files and run any terminal commands right now.
The goal for this chapter is to learn more about the sandboxes, how they work, and basically to create a template that we are going to use moving on to create working Next.js applications. So we're going to start by creating an E2B account. You can use the link in the description or the link you can see on the screen to let them know you came from this video. As you can see, in short, E2B allows you to run AI generated code securely in your application. It's an open-source runtime for executing AI-generated code in secure cloud sandboxes.
It is made for Gentik and AI use cases. And some of their customers are Perplexity, Hugging Face, Manus, and even Grok. So these are very, very big names in AI here. And my experience with E2B was nothing short of amazing. So they are built for AI use cases.
So for exact thing that we are building, here it is. Generative UI. This is pretty much the thing that we will be building here. But they have an even deeper use case, which I highly invite you to explore yourself. So let's go ahead and create an account, and let's go in the dashboard.
After you create an account, you will probably be redirected to your sandboxes, which looks like this. And at the moment, you will probably have zero sandboxes running. If you head into templates, you will probably have less templates than I do. You might have three. I have five templates because, well, I explored E2B while I was developing this project.
You can see that I have this code with Antonio next JS thing. You don't have this. So I have this because I tested it. Same thing with this no-name template, right? You probably have desktop, code interpreter, and base.
I assume that's the things you have. You probably don't have these two. So no worries about that. And I just want to show you inside of your budget you should see your credits. So you should have $100 free for your new account.
And as you can see I tested E2B pretty thoroughly. So I really really tested it all day every day and they barely spent $9. So it is quite well optimized for tutorial making. So ensure that you have that in your budget, make sure that you have the credits. And now let's go ahead inside of the documentation here and specifically let's go in the CLI installation.
So you can use brew or you can use npm. I used npm here and once you do that you should be able, my apologies for this, you should be able to run e2b right and you should see a bunch of options on how you can run it. And you can shut down your app, right? So basically, E2B should become available after you install either via NPM or using Brew. So what we have to do next is we have to authenticate, right?
So E2B auth login should open up. You can see that I'm already logged in. So in here I get that message, but you should get a... You probably won't get this message. Instead, you will get redirected to E2B page and from there you're gonna have to approve the login and then you'll be good to go.
So once you've logged in, what I would suggest is try listing sandboxes or just try listing something just to confirm that you are logged in. So I have no running sandboxes so this is my message. I believe that if I wasn't logged in I would get some kind of error here, right? So just make sure that at least you get a message like this, which means, okay, you're logged in, but you have no running sandboxes. Great.
So now what we have to do is we have to learn how to add a new template, because right now you can see that inside of our E2B here, templates, you probably have three of them, as I said, desktop, code interpreter, and base. But what you need is a Next.js template. Now, they do have their own Next.js template which you can use but I don't want you to do that. I want you to learn how to create your own template. So for this we're gonna have to go into the second step.
So we've created CLI and we've connected to our account. Now we need to create a Dockerfile template. Now I have provided you with a GitHub repository with two files that we are going to need for this. Not because I don't want to write this with you but because we have to be very careful about writing these files, right? So this is what I suggest we do now.
As always ensure that you're on your main branch, you can synchronize changes just in case, And then go inside of your source folder here. My apologies, outside of source folder. So completely outside. Create a new folder called sandbox-templates. Like this.
And inside create a new folder which we're going to call next.js. And then in here, you are going to create a e2b.docker file like this. You don't have to install any extensions, at least I didn't use any for this. Now, this Docker file has the content that you can find in the public repository which you can access by using the link in the description or the link you can see on the screen. And when you're in here, you can access that file.
So just go ahead and copy it entirely and paste it here. And now we're going to go ahead and explain what it does. So the first thing we do is we set the environment. In our case, that's going to be node. After that, we run a terminal command to install curl.
So we updated the system, we get the install method for curl, and then well whatever else we need to do here. I'm not too familiar with configuring Docker environments but basically in this part we configure curl. After that what we do here is we copy another important file, a bash script, compile page, which we currently don't have. So let's create it. Compile underscore page dot sh.
Make sure to not misspell this because we need it right here. And you can find the content in the same public repository here. I'm going to explain what this does as well. But for now, just make it like this. After we copy this compile page and we put it in the environment, right, in this Docker environment, we run this command on it to make it executable.
Then we change our directory to nextjs-app. And then inside of that nextjs-app, we run a command which you've already seen a couple of times, create-next-app. So basically the same way we started this project, we are now creating a Docker which is going to start the project the same way. The versions I'm using are 15.3.3 with ShadCN 2.6.3. The reason I'm using these versions is because when I started making this tutorial, those were the newest versions.
You already know that now that I'm recording this tutorial, there are newer versions than this. So if you want to, you can upgrade. But I'm going to stay with these versions for now, simply because I know that they work for me. So later on when we finish the project, you know, feel free to upgrade this to 7.0 and this to 7.0 and this to whatever is the newest version. But for now I want to stick with these versions because they worked for me initially.
Now let's explain these flags. So why do I add dash dash yes after npx? And why do I add dash dash yes after create next app? The reason I'm doing that is because you have to remember, these commands will be running in a container, in a dockerized container, which means no user will be able to interact with them. Remember when we started our Next.js application, we had a bunch of questions.
Do you want to use Tailwind? Do you want to use SLint? Do you want to use this, that? So because of that, I have to just agree to all of those things so the terminal doesn't hang, right? So it doesn't block.
It can keep moving forward. Because if it blocks, it will not work. That's why we have to add both //yes in front of npx and in front of our command. Because npx might ask you to upgrade, right? So we will also agree to that, right?
Whatever you ask me, I agree to. And same is true for running ShadCN init and for adding all ShadCN components. And then what we do is the following. We move the content of that new folder, next.js app, where we just added Next.js and all of its components, and we move that entire content into home user directory. And then we remove the old folder.
The reason we do that is simply because it is easier for AI to understand that the place where it's located, because initially it will be loaded here, we just tell it wherever you are, this is where you have the Next.js application. You don't have to go to any other directory. Trust me, that is much easier for an AI to understand, because otherwise it will hallucinate things. This way, it's just easier to work with. So you might be wondering, why did we then even open a new folder if we're just going to bring all the stuff back here?
Because if you try to initialize this command, the dot basically means in this folder. If you try to do that inside of home user, it would fail. Because in order to initialize the next app, it needs to be an empty folder. And home user has some hidden files, right? So it's never really empty.
That's why we needed to do this trick. So that is basically our Dockerfile. Now let's explain the compile page. So the compile page is a little trick that we are going to use to ensure that the Next.js application is running and that the root page is compiled. So basically in here we have a function called pingServer which uses curl which we install right here and we are attempting to ping localhost 3000 And we are doing an iteration of 20.
I'm not sure, not too familiar with the Bash shell language to tell you if this is seconds, milliseconds, I'm not sure. But basically it's more than enough time for the server to start. So it gives it 20 attempts, right? To try and get a 200 response. And once it does, it simply marks it as done.
And then it runs that method, ping server, and it goes inside of home user, where we just said that we create this project, and it runs npx next dev dash dash turbo pack. So the turbo pack is really cool here because it speeds up the start of the dev server. So it's actually very useful in this case. Great. So once you have these two things, the second part is very important.
And that is that you set up Docker inside of your project. So here I am on the Docker landing page. You can use the link you can see on the screen to let them know you came from this video. And basically the way I set up Docker in my project is by downloading Docker Desktop. I use a MacBook, so I download it for Apple Silicon.
If you use Windows, you choose your architecture here, or if you use Linux, well, you probably know what you're doing then. So after you've done that, make sure that you have Docker installed. So in here, let me just try and open it back here. So if I go inside of let me just try and find a documentation here. Docker desktop.
Let's go into overview and in here somewhere we should have setup install and in here there we go. So in here we have some deeper documentation here. On Mac and on Linux it's pretty straightforward, right? If you install it with a DMG, it will add it to the terminal as well. But if you don't, here's how you can add it from terminal as well.
Also, if you want to, you can use Orbstack. That's a Docker alternative. But the reason I don't know how to explain how to install Docker is because I don't know if I'm talking to a person who has a Windows, who has Linux, or who has Mac OS. So that's why I don't want to give you too much information and I don't want to tell you something incorrectly. But basically, try to research yourself.
You know what you are using, right? So try and install that. And your goal is basically to be able to have Docker available. Right? That's kind of the goal.
You should not get an error in Docker. And on the Windows in here, you can see pretty similar instructions. I'm not too sure what this means. I don't use Windows. But in here, I think it is important for you to be able to run Docker from the command line as well.
But at minimum, you need to install the Docker desktop package and you should be able to start that application at minimum. That's the minimum thing that I expect. So now I'm going to go ahead and start my Docker application. Actually, the first thing I'm gonna do is I'm gonna try without Docker started, simply so we can test if the command fails. So I want to show you what happens if the command fails first.
So let's go ahead inside of SDK reference, CLI, template, and let's do template build. So in here we have E2B template build command and the way we're gonna do this is the following. Go inside of sandbox templates and go inside of Next.js, like this. So I'm going to try and run e2b-template-build here. And I'm going to give this a name and I'm going to call it vibe-nextjs-test.
So that will be the first thing I'm going to try. So in here, you can see how it found the E2B Docker file and it requested build for the sandbox template ID with this name. Login succeeded. And then it attempted to run Docker build. And then it failed.
Right? So this is the error you will see if your Docker is not running. So now I'm going to start Docker. For me, very simply, I'm just going to open the application Docker. And then in here, I will have Docker Desktop available.
You can see Docker Desktop is now running. So Let's see if that will be enough for me to run this and try it. So let me see, e2b-template-build. Let's see this time. And there we go.
So all I had to do was install Docker Desktop, and I need to make sure that I have Docker desktop running. That's the important thing for me. So you can actually stop this now because it will take some time to build, but it's not going to work correctly. I just wanted to show you how it looks like when your Docker is not running. Basically, this is the error you will get.
So just make sure you have Docker running. You don't even have to create any image on Docker or nothing. We are doing that now, right? So just make sure you have Docker installed on your system and make sure you open whatever application you installed. It can be Orbstack, it can be Docker Desktop.
I'm not sure if you need it inside of here. I keep saying that because I don't know what machine you're on. I have it inside of my terminal as well. I'm not sure if that matters. Because you can see that in here, it does run the docker command.
So it probably does matter the fact that I have it inside of my terminal. So make sure that you have docker-cli installed as well. If you don't, you might even see a different error showing here. Great. But once you get to this part, once you get to the fact that after Docker build is being fired, you start seeing these kinds of messages, right?
Something resolving, something transferring. It means the Docker is working. And then you can cancel it using Command C or Control C. And then we're going to run a proper command with a proper start command. So now in here, here's what we have to do.
This basically, we have to add e2b template build dash dash name vibe next JS vibe nextjs test2 dash dash cmd and you have to add compile underscore page dot sh so now Let's go ahead and run this again. So I'm just going to wait to see this succeed. There we go. And now I'm going to pause until this part completes because it is a little bit long. It needs to upload the entire Next.js project there with all the packages and everything.
And it needs to install curl and all of that. So I will pause until some interesting things show here so you can compare with your process as well. So here's an interesting part. It is running npx create-next-app. And you can see my result.
TypeScript, types-node, types-react, tailwind-css. So it is obviously successfully installing this with no questions asked. That's why these parts were so important because if we didn't include this it would be blocked by waiting for the user input, right? That's why that is important. It was also successful in copying compilePage.sh so we did this correctly as well now I am running a chat CN in it I'm selecting neutral color I'm forcing everything to install here right So I'm just making sure that I'm not adding any prompts.
And there we go, it's succeeding. It checked the registry, it found app global CSS, and now it's installing all dependencies. So, so far, so good. Now it is adding all components. You can see again, very successful.
It found global CSS, it is upgrading it and it is installing all of those Radix packages, which we use for our components. So We are basically doing the same setup we did for our project but this time inside of a docker container. Great! And now it has finished that part and now it is moving the entire content from Next.js app into home user and removing the old folder. Now, this command actually failed for me a lot during the initial development of this project.
And the reason was actually because I was missing this dash dash yes commands. So if this part is successful for you, as it is to me right now, you have pretty much succeeded in doing this. So if this part fails for you, it is almost certainly because you forgot to add "-yes", to some of this. Basically, it's hanging on some command and it didn't create the next JS app. Great.
So now what's happening, I think, you know, I'm new to Docker as well. I've briefly experienced it before. But now what's happening is obviously pushing all of that data to the Docker container on the E2B app. And just to confirm in case you're wondering, this part does take a while. After that part has completed, it is triggering the build.
And here you can track the progress of the build itself. So this is more specifically a build of the Docker image. We're not building the Next.js app. Those are two different things. Our Next.js app is just a development instance.
We are building the Docker image here. Alright, so mine failed. So I will... It looks like it failed because... It is missing the compile underscore page dot sh command not found.
And that's definitely because of this. I should have done this differently. I have to find a way to execute this in a different way. Something like this. I will test it out so I know for sure, and then I will tell you the correct command.
So I think that the start command should be this, forward slash compile page dot sh. And let me just show you something. Regardless if this part fails or not, I mean depending on how I edit this video perhaps I told you not to even run this command in advance, right? But you can see that I have something called e2b.tumble generated. In here, you can see my start command is compile underscore page dot sh.
So I have two ways of changing this now. I can either change it here or I can change it here. But you can see how it remembered all of these things. But for now, basically, this should be the working command. So I'm going to pause and try it again.
And this time it worked. You can see that right here, it is waiting for the template to be ready. And then it is waiting for server to start a couple of times. And then finally we can see Next.js 15.3.3. And that signals that it is done.
Template is ready, pausing Sandbox template. So be very, very careful here. During my initial development of this project, I was able to get to template is ready and pausing sandbox template and uploading template, but I actually never saw this part. Let me just go up here. It is very important that you can see this part in your terminal because this means that it's actually working.
If you can't see this everywhere, even with this saying it's ready, it will actually not be working. So just make sure you did this correctly. And also on the second run, this runs much, much faster because half of the, I mean, the entire project is already uploaded, right? So you won't have to wait that long. But basically, this was the final command, E2B template build.
And the cool thing now is that you actually get instructions on how to use this, you can see that you can use the name, or you can use the ID. So I don't know what this actually tells us. Is the name unique or not? I think it might be unique per team, which then, again, depends if you're going to publish this or not. What does publishing mean?
Well, I'm going to explain in a second. But basically, now you can go find your e2b.toml file. And in here, you can see all the information team ID, start command, Docker file, template name, template ID. And from now on, if you ever want to do any changes to here, you can just do template build. That's it.
And you can just modify whatever you want from here want to change the name just change the name here and run template build so right that in the tomo file that's basically where the configuration is now great so before we move on now let's go ahead inside of E2B, inside of your project, go inside of templates and refresh. And now if you have done this correctly, you should see vibe-nextjs-test-2 right here. And you can see that this says private. So just to make things easier for now, I want you to do the following. I want you to copy the ID of vibe next JS test two.
And I want you to go and go to E2B template publish here. And let's go ahead and do the following. So actually, we need the team ID, my apologies. So just go ahead and find, I think it's inside of your team here. Find the team ID and copy it.
And inside of here, so you are inside of this next.js template so you can just do e2b template publish dash t and then paste the id of the team and this will make the template public to everyone outside of your team. The reason you're doing this is simply because it will be easier to connect to it. At least that was my experience. Later on, we can easily unpublish it or you can delete it. The reason this is kind of, you know, you should be wary of this.
You should not share your template ID with anyone because I can use it and I can use your credits, right? I can spend your budget here. So be careful, make sure that only you know about this. And later I will make sure to find a way to unpublish this so that only you and your team can use this. Great, so now what should happen is inside of your templates when you hit refresh and find that vibe-nextjs-test2 it should say public under visibility And that basically means you did it.
This is now working. So now what we have to do is the last part of this chapter, we did this, we did this, and we even did this. It's time to actually start this sandbox, right? Let's see if that Next.js app is actually working or not. And lucky for us, this is quite easy to do.
So what we're gonna do now is we're gonna go inside of source, inside of ingest and inside of functions here. And I think I've completely forgot, but yeah, we have to install e2b. I think I forgot that entirely. So let's add e2b code interpreter to our project. And make sure you go in the root of your app like this and I'm going to show you the version of this package now so let's go inside of package.json quickly so it is 1.5.1 that's my version Now let's go inside of our functions here.
And let's import sandbox from E2B code interpreter package, which we just installed. And then what we're going to do is the following. Let's go ahead. And before we create an agent, let's do const sandbox ID await step.run. And we can extract the step from here.
We removed it in the previous chapter, I believe. So step.run get sandbox ID. That will be the first step we're going to run. And in here, we're going to attempt to get the sandbox by doing await sandbox.create. And inside of here, you will simply pass the template ID.
So in your case, this will be Vibe Next.js test2. Now, you will probably have a different name for this, because I think if they allow public templates, there probably has to be some kind of originality here, I guess. So once you've created that, go ahead and simply do await sandbox setTimeout. Actually, you don't have to change the timeout. I'm going to explain what the timeout is in a second, but for now Let's just do sandbox.sandboxid.
So this will be the step which we are actually going to preserve here and keep throughout this entire project because we will always need the sandbox ID. And now that we have the sandbox ID, what we have to do is we have to create a sandbox URL. So after the agent finishes, let's pretend that this agent now actually connected to this sandbox and then added a bunch of files. Then what we would do is we would generate the sandbox URL using await step.run get sandbox URL. In here, we would get the sandbox again using await.
And then in here, we need to create a util called get sandbox. So let me just go ahead inside of the ingest and create utils.ts and export asynchronous function getSandbox which accepts sandbox ID which is a type of string. Let's get the sandbox using await sandbox from e2b code interpreter dot connect sandbox ID like this. And then in here just return sandbox. So basically I'm writing a function to make this reusable.
You're going to see why later. And also, let's import this like so, so the structure. Now that you have getSandbox, you can do a wait getSandbox here and pass in the sandbox ID. And then return sandbox.gethost 3000. So basically what this is, it creates the host under the port 3000.
Why 3000? Well, we know why, because of our sandbox template, right? Inside of here, we know it's running on port 3000. That's the only port it can run on. It's a Next.js app.
And this is actually only the host. So let's do const host to be that, and then return, open backpicks, HTTPS, and then host, like this. And then in here, sandbox URL, like this. Are you ready to try this out now? Make sure you have imported the get sandbox, right?
So let's go ahead and do it. Npm run dev in one, npx ingest cli latest dev in the other. It is running, perfect. Let's go to localhost 3000. Make sure you have your InGIS development server here.
And I'm just going to do create a button component again, why not? And let's go ahead and see what's going on here. Oh, so there we go. It is failing. So something, you can see the error, invalid API key.
So we can cancel this run because I forgot to add the API key. I'm constantly not reading this the way I should. So let me just go ahead and click on API key here. And we can find it at the dashboard. So let's go back inside of our dashboard here.
You can see I already have some. So I'm going to click Create New Key here. And you can find it here under API keys. So Create New Key, Vibe, Dev. And I'm going to click Create Key here.
I'm going to copy that key, and let's go inside of .environment here, E2B, and let's add it. So it's going to be E2B API key, like that. And if you add it like this, I don't think you have to explicitly add it anywhere, because this is what it will be looking for. So I'm not sure if I can find the documentation for this specifically, But I think that now it will be working. Let's try again.
Invoke another background job. And let's see. Do we get any errors, or do we successfully get a running template? We're going to see getSandboxId has succeeded. And now it's doing the coding agent thing.
It's generating some code. And now it's grabbing the sandbox URL. And in the finalization here, you should see the output of an AI who created a component. And you should see an actual URL. Let's try and visit this URL.
Fingers crossed, and we should now see a Next.js application. And we are! A completely empty Next.js application hosted in E2B started from our background job. You are halfway there. You can already kind of tell what the next steps are.
We are going to dive deeper into E2B Sandbox API now and we're going to learn how to run terminal commands, how to create files, how to read files, basically how to translate what it's now doing here very simply as an output into actually modifying the code in this sandbox. Amazing, amazing job. I know this chapter wasn't too easy, a lot of new things, Docker, Docker files, all of those things. But if you've come this far, you did it. Amazing, amazing job.
So let's go ahead and mark this as complete. And yes, this will stop working after some time, and that's completely normal. So after about five minutes, I think by default, this link will show an error. So that's normal. Don't worry.
We can change the timeout later. So now let's go ahead and let's merge this. So I'm gonna go ahead and I'm going to open my source control here. I'm gonna go ahead and create a new branch. 06e2b sandbox.
Let me just confirm that's my chapter name. So sandboxes. I'm going to go ahead and stage all of my changes, including the Docker files, of course. And I'm going to do 06e2b sandboxes here, and I'm going to commit, and I'm going to publish my branch. Again, there is a free CodeRabbit extension you can use if you want to review your changes and learn about all the things you can do differently in your code.
So if you want, you can click Review All Changes, or if you're like me and you like to see the summary and all other things, you can use their pull request function. So now I'm opening my new pull request here, which I will merge. So let's go ahead and review it. And here we have the code summary. So what I'm very impressed with is how well CodeRabbit understands what we just did.
So we introduced a sandbox environment for Next.js, allowing users to create and access isolated Next.js instances. We added functionality to generate and return a unique URL for accessing sandboxed Next.js app. So quite impressive that it understood the entire context of this pull request with nothing more than files. Very, very, very nice. So in here, we even have an entire sequence diagram demonstrating how that happens.
So once the user triggers a Hello World background job, we go ahead and create a new sandbox with our template name. After that, we return the sandbox id and we have it for that session of that background job. We then use our new package, E2B Code Interpreter, to return a sandbox instance and from it we extract the sandbox URL. Amazing! And you can see how it even has some related pull requests.
It detected where we initially added Hello World, so if you were working in a team, if this was some big operation, you can now link pull requests automatically with this extension. Amazing. So in here it has some potential issues regarding our toml file, but that doesn't matter because this file is not generated by us in the first place, so it is okay for it to be like this. In here it is suggesting improving the compile page shell script which could be completely valid. I don't know bash, I'm also mixing bash and shell, I'm not even sure what is the correct name.
So for all I know, this could be completely correct. But since I want to be very careful about this part, you know, I'm not going to change it because I know it works, right? So good enough for me at the moment great so in here it recommends adding some try catch all of the things which we will add later but in a different syntax because we will implement the agent network and the agent retrying and it's gonna work in a different way it's gonna be using tools. So overall pretty good summary pretty good review let's go ahead and merge this now. As always I'm not going to delete my branch simply so I have access to all of my progress here.
Amazing amazing job! So as always go back to your IDE here and change the main branch and then click on synchronize changes and as a final sanity check you can go ahead inside of source control inside of graph and you will see 06 E2B sandboxes have just been merged. Amazing, amazing job. I believe that marks the end of this chapter and see you in the next chapter where we are going to learn how to make our AI use tools such as terminal to install some things and actually modify these sandboxes. Amazing, amazing job.