> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Ruby on Rails > Deploy a Ruby on Rails application to Magic Containers This guide walks you through building and deploying a Ruby on Rails application to Magic Containers with GitHub Container Registry. You'll need: * A GitHub account for source code and container registry * Ruby 3.2+ installed locally > [!TIP] > > Don't have a bunny.net account yet? [Sign up](https://dash.bunny.net/auth/register) and enable Magic Containers to get started. ## Create the Rails app > [tab] Full-stack > > Create a new Rails application with views and assets: > > ```bash theme={null} > rails new app-rails > cd app-rails > ``` > > Generate a controller with a view: > > ```bash theme={null} > bin/rails generate controller Home index --skip-routes > ``` > > Add the route in `config/routes.rb`: > > ```ruby config/routes.rb theme={null} > Rails.application.routes.draw do > root "home#index" > get "up", to: "rails/health#show", as: :rails_health_check > end > ``` > > Update the view in `app/views/home/index.html.erb`: > > ```erb app/views/home/index.html.erb theme={null} >

Hello from Bunny 🐰

> ``` > [tab] API only > > Create a new Rails API application: > > ```bash theme={null} > rails new app-rails --api > cd app-rails > ``` > > Generate a controller with a simple endpoint: > > ```bash theme={null} > bin/rails generate controller Api::Health index --skip-routes > ``` > > Add the route in `config/routes.rb`: > > ```ruby config/routes.rb theme={null} > Rails.application.routes.draw do > get "/", to: "api/health#index" > get "up", to: "rails/health#show", as: :rails_health_check > end > ``` > > Update the controller: > > ```ruby app/controllers/api/health_controller.rb theme={null} > class Api::HealthController < ApplicationController > def index > render json: { message: "Hello from Bunny 🐰" } > end > end > ``` ## Run locally Start the Rails development server: ```bash theme={null} bin/rails server ``` Test the app at [http://localhost:3000](http://localhost:3000), or with curl: ```bash theme={null} curl http://localhost:3000/ ``` ## Prepare for production Rails 7.1+ automatically generates a production-ready `Dockerfile` in your project root. Before building, prepare the app: ```bash theme={null} bin/rails db:migrate rm config/credentials.yml.enc ``` The credentials file is removed since we'll use environment variables instead. > [!NOTE] > > If you're using an older Rails version, you can generate a Dockerfile with: > `bash bin/rails generate dockerfile ` ## Review the Dockerfile Rails 7.1+ generates a production-ready, multi-stage Dockerfile that includes: * **jemalloc** for reduced memory usage * **Bootsnap** precompilation for faster boot times * **Non-root user** for security * **Asset precompilation** (full-stack apps only) * **Thruster** HTTP/2 proxy (full-stack apps only) ## Build and push to GitHub Container Registry > [tab] GitHub Actions > > Create `.github/workflows/build.yml` to automatically build and push on every commit to `main`: > > ```yaml .github/workflows/build.yml theme={null} > name: Build and Push > > on: > push: > branches: [main] > > env: > REGISTRY: ghcr.io > IMAGE_NAME: ${{ github.repository }} > > jobs: > build-and-push: > runs-on: ubuntu-latest > permissions: > contents: read > packages: write > > steps: > - uses: actions/checkout@v4 > > - name: Log in to GitHub Container Registry > uses: docker/login-action@v3 > with: > registry: ${{ env.REGISTRY }} > username: ${{ github.actor }} > password: ${{ secrets.GITHUB_TOKEN }} > > - name: Build and push > uses: docker/build-push-action@v5 > with: > context: . > push: true > tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} > > - name: Update container image on Magic Containers > uses: BunnyWay/actions/container-update-image@main > with: > app_id: ${{ vars.APP_ID }} > api_key: ${{ secrets.BUNNYNET_API_KEY }} > container: app > image_tag: "${{ github.sha }}" > ``` > > Push your code to trigger the workflow: > > ```bash theme={null} > git init > git add . > git commit -m "Initial commit" > git remote add origin https://github.com/YOUR_USERNAME/app-rails.git > git push -u origin main > ``` > [tab] Docker CLI > > Build and push manually from your local machine. > > **1. Create a Personal Access Token** > > Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens) and create a token with `write:packages` scope. > > **2. Log in to GitHub Container Registry** > > ```bash theme={null} > export CR_PAT=your_personal_access_token > echo $CR_PAT | docker login ghcr.io -u YOUR_USERNAME --password-stdin > ``` > > **3. Build the image** > > ```bash theme={null} > docker build --platform linux/amd64 -t ghcr.io/YOUR_USERNAME/app-rails:latest . > ``` > > > [!NOTE] > > > > Magic Containers only supports images built for the **linux/amd64** architecture. The `--platform` flag ensures compatibility regardless of your local machine's architecture. > > **4. Push to registry** > > ```bash theme={null} > docker push ghcr.io/YOUR_USERNAME/app-rails:latest > ``` > [!NOTE] > > If your package is private, set the visibility to **Public** in GitHub or > [configure Magic Containers with registry > credentials](https://bunny.net/docs/magic-containers/image-registries.md). ## 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: | Field | Value | | - | - | | Registry | GitHub Container Registry | | Image | `YOUR_USERNAME/app-rails` | | Tag | `latest` | **3. Configure environment variables** Go to the **Environment Variables** tab and add: | Variable | Value | | - | - | | `SECRET_KEY_BASE` | Generate with `bin/rails secret` | **4. Add an endpoint** Go to the **Endpoints** tab, click **Add New Endpoint**, and set the container port to `80`. **5. Deploy** Click **Add Container**, then **Next Step**, and **Confirm and Create**. For more details, see the [quickstart guide](https://bunny.net/docs/magic-containers/quickstart.md). ## Test your app ```bash theme={null} curl https://mc-xxx.bunny.run/ ``` ```json Response theme={null} { "message": "Hello from Bunny 🐰" } ``` > [!NOTE] > > You can [add a custom hostname](https://bunny.net/docs/magic-containers/endpoints.md) from the **Endpoints** section in your app settings. ## Add persistent storage Magic Containers are ephemeral, so data stored locally is lost on restarts. For Rails apps that need to persist data (Active Storage uploads, etc.), attach a [Persistent Volume](https://bunny.net/docs/magic-containers/persistent-volumes.md). **1. Add a volume** Go to your app's **Volumes** tab and click **Add Volume**. Set the mount path to `/rails/storage` and choose an initial size. **2. Configure Rails storage** Update `config/environments/production.rb` to use the volume for Active Storage: ```ruby config/environments/production.rb theme={null} config.active_storage.service = :local ``` **3. Configure SQLite (optional)** To persist your SQLite database, update `config/database.yml`: ```yaml config/database.yml theme={null} production: <<: *default database: /rails/storage/production.sqlite3 ``` See the [Persistent Volumes documentation](https://bunny.net/docs/magic-containers/persistent-volumes.md) for more details. ## Next steps 1. [Automate deploys with GitHub Actions](https://bunny.net/docs/magic-containers/deploy-with-github-actions.md) 2. [Add a custom hostname](https://bunny.net/docs/magic-containers/endpoints.md) This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.