• Docs
  • Changelog
Sign in
Get started
    • Home
    • Your first deploy
    • Free instances
    • Platform features by plan
    • Use with coding agents
    • FAQ
    • Templates
      • Migrate from…
        • Heroku
        • Railway
    • Compute plans
    • SandboxesBeta
      • Service types
        • Which to use?
        • Static sites
        • Web services
        • Private services
        • Background workers
        • Cron jobs
        • Workflows
        • Multi-service architectures
      • Data storage
        • Render Postgres
        • Render Key Value (Redis®-compatible)
        • Persistent disks
    • How deploys work
    • Supported languages
    • Git providers (GitHub, etc.)
    • Build pipeline
    • Deploy hooks
    • Monorepo support
    • Troubleshooting deploys
      • Previewing changes
        • Single-service previews
        • Preview environments (multi-service)
      • Docker deploys
        • Overview
        • Deploy a registered image
        • Using secrets
      • Runtime
        • Native runtimes
        • Environment variables & secrets
        • Default environment variables
    • Intro to sandboxes
    • Limits
      • How to…
        • Create & configure sandboxes
        • Execute commands
        • Manage files
        • Manage snapshots
      • Use with…
        • Claude Managed Agents
        • Cursor Cloud Agents
        • OpenAI Agents API
      • SDK/CLI reference
        • TypeScript SDK
        • Python SDK
        • CLI commands
    • Intro to workflows
    • Tutorial
    • Limits & pricing
      • How to…
        • Define tasks
        • Define flowsNew
        • Trigger runs
        • Develop locally
      • SDK reference
        • TypeScript SDK
        • Python SDK
      • Example workflows
        • TypeScript examples
        • Python examples
    • Overview
    • Create & connect
    • Database credentials
    • Extensions
    • Version upgrades
    • Logical replication
    • Legacy instance types
      • Database recovery
        • Recovery & backups
        • High availability
      • Database performance
        • Read replicas
        • Connection pooling
        • Admin apps
        • Repacking tables
        • Troubleshooting performance
    • Regions
    • Inbound IP rules
    • Edge caching
    • WebSockets
    • TLS certificates
      • Custom domains
        • Overview
        • Cloudflare
        • Namecheap
        • Other DNS providers
      • Internal traffic
        • Private network
        • Private links
      • Outbound traffic
        • Default IP ranges
        • Dedicated IP addresses
        • Outbound bandwidth
        • Handling network changes
      • Static site config
        • Custom response headers
        • Redirects & rewrites
    • The Render Dashboard
    • SSH / Shell access
    • Projects & environments
      • Service actions
        • Scaling
        • Rollbacks
        • Maintenance mode
        • One-off jobs
      • Infrastructure as code
        • Blueprints overview
        • render.yaml reference
        • Terraform provider
    • In-dashboard metrics
    • Health checks
    • Uptime best practices
      • Logging
        • In-dashboard logs
        • Log streams (syslog/HTTPS)
      • OpenTelemetry (OTel) metrics
        • Provider setup
        • Metrics reference
      • Notifications
        • Webhooks
        • Email / Slack
    • MCP Server
      • Render CLI
        • Overview
        • Command reference
      • REST API
        • Overview
        • API reference
      • Third-party connections
        • OIDC support
        • Datadog
    • Workspaces, members, & roles
    • Login settings
    • Audit logs
      • Organizations
        • Overview
        • SAML SSO
    • DDoS protection
    • Platform maintenance
      • Compliance
        • Overview
        • HIPAA (US health data)
        • HIPAA best practices
        • Shared responsibility model
        • Pentest policy
    • Heroku vs Render
    • Vercel vs Render

Deploy a Phoenix App with Distillery

This is a guide to deploying Phoenix projects on Render using Distillery.

We'll start off with a bare Phoenix project with Ecto, modify it to use Distillery, and deploy it on Render. The full source code for this tutorial is available at https://github.com/render-examples/phoenix-distillery.

Create a Phoenix App with Distillery

  1. Create a new Phoenix app in the terminal:

  2. Update mix.exs to add Distillery to deps:

    Then run mix deps.get in your terminal to update dependencies.

Configure Distillery

  1. Let's configure Distillery for production. Update the Endpoint config in config/prod.exs so it looks like this:

    Read more about Distillery configuration.

    We're not going to check secrets into source control. Instead, we're going to manage them in production with Render environment variables. So let's delete the line at the end referring to prod.secret.exs.

    And delete the file config/prod.secret.exs.

  2. You're now ready to initialize your Distillery release.

    This will create rel/config.exs, rel/vm.args, and the empty directory rel/plugins.

    rel/vm.args is used for runtime configuration by default, but we're going to use the Mix Config Provider instead so you can delete this file.

Creating a Mix Config Provider

  1. Create a Mix configuration file at rel/config/config.exs:

    Contents of rel/config/config.exs :

    This sets up the Mix configuration provider to get values from runtime environment variables.

  2. Update rel/config.exs to use your new provider. Change the environment :prod section in the file to this:

Configuring Ecto

Let's configure Ecto to get the DATABASE_URL from the environment. Change lib/phoenix_distillery/repo.ex so it looks like this:

Build a Release with Distillery

You're now ready to build and run your first release!

The output should look like this:

You can now test your release (assuming PostgreSQL is up on your local machine):

You can now deploy your app in production! 🎉

Deploying to Render

  1. Create a build script called build.sh at the root of your repo:

    Make the script executable before checking it into Git:

  2. Create a new PostgreSQL database on Render.

  3. Create a new Web Service on Render, and give Render permission to access your new repo.

  4. Use the following values during creation:

    LanguageElixir
    Build Command./build.sh
    Start Command./_render/bin/phoenix_distillery foreground

    Also add these environment variables to the web service:

    KeyValue

    SECRET_KEY_BASE

    A sufficiently strong secret. You can generate a secret locally by running mix phx.gen.secret

    DATABASE_URL

    The internal database URL of the database you created above.

Going forward, every push to your repo will automatically build your app and deploy it in production. If the build fails, Render will automatically stop the deploy process and the existing version of your app will keep running until the next successful deploy.

Read about customizing Elixir and Erlang versions for your app.

Deploy a Phoenix App with Distillery
  • Create a Phoenix App with Distillery
  • Configure Distillery
    • Creating a Mix Config Provider
    • Configuring Ecto
  • Build a Release with Distillery
  • Deploying to Render
All Systems Operational
© Render Inc. All rights reserved.