- A GitHub account for source code and container registry
Create the Next.js app
Create a new Next.js project:Configure standalone output
Update yournext.config.ts to enable standalone output mode for Docker:
next.config.ts
Create an API route
Create a simple API route to test the deployment:app/api/route.ts
Run locally
Start the development server:Create the Dockerfile
Dockerfile
Pass build-time variables
next build inlines NEXT_PUBLIC_ variables and bakes in anything next.config.ts reads, and docker build doesn’t read your shell’s environment. Declare each one as an ARG in the builder stage, or the build runs without it:
Dockerfile
docker build --build-arg NEXT_PUBLIC_CDN_URL=https://myapp.b-cdn.net, or with build-args in docker/build-push-action.
Build and push to GitHub Container Registry
- GitHub Actions
- Docker CLI
Create Push your code to trigger the workflow:
.github/workflows/build.yml to automatically build and push on every commit to main:.github/workflows/build.yml
If your package is private, set the visibility to Public in GitHub or
configure Magic Containers with registry
credentials.
Deploy to Magic Containers
1
Create a new app
In the bunny.net dashboard, go to Magic Containers and click Add
App. Enter a name and select your deployment option.
2
Add a container
Click Add Container, then configure:
3
Add an endpoint
Go to the Endpoints tab, click Add New Endpoint, and set the
container port to
80.4
Deploy
Click Add Container, then Next Step, and Confirm and Create.
Test your app
Visit your container URL in the browser to see your Next.js site, or test the API route:Response
You can add a custom hostname from the Endpoints section in your app settings.
Add Optimizer
Your CDN endpoint is already a pull zone in front of the app. Turn on Bunny Optimizer there, andnext/image resizes images at the edge.
1
Configure the endpoint's pull zone
Open the pull zone that serves your CDN endpoint under CDN → Pull Zones. Turn on URL Query String vary, since endpoint pull zones ignore query strings by default and
?width=1080 would come back as the cached ?width=640 image.Enable Optimizer, then turn on the Dynamic Image API and automatic WebP under Optimizer → Settings. Next.js already minifies CSS and JavaScript, so turn Optimizer’s minification off.2
Add the image loader
The loader turns each
next/image width into an Optimizer URL. With NEXT_PUBLIC_CDN_URL unset, it returns relative URLs that go through the same pull zone.lib/bunny-loader.ts
3
Point Next.js at the loader
next.config.ts
Connect a database
You can connect your app to Bunny Database directly from the dashboard:- Go to Database > [Your Database] > Access
- Click Generate Tokens
- Click Add Secrets to Magic Container App
- Select your app
BUNNY_DATABASE_URL and BUNNY_DATABASE_AUTH_TOKEN environment variables are now available in your app:
app/api/users/route.ts