DEV Community

Cover image for How to Deploy a Full Stack App to Koyeb Using Docker Compose and GitHub Actions
EphraimX
EphraimX

Posted on

How to Deploy a Full Stack App to Koyeb Using Docker Compose and GitHub Actions

When building full-stack applications with Docker Compose, it’s essential to have a reliable way to ship and deploy both frontend and backend services in sync. This article walks through setting up a CI/CD pipeline using GitHub Actions to deploy a multi-container Docker application to Koyeb, a modern platform that supports containerized workloads out of the box.

We’ll use a real project—complete with frontend, backend, and supporting services—as our base. The focus here isn’t just deployment, but doing it cleanly and automatically through GitHub Actions. You’ll see how to:

  • Prepare your application with Docker Compose
  • Configure GitHub Actions workflows for CI and deployment
  • Push both services to Koyeb in a unified pipeline

By the end of this guide, you’ll have a production-grade deployment pipeline that pushes changes from main to Koyeb, without manual steps or scripts. The project code is available here if you’d like to follow along.

Table of Contents

  1. Prerequisites
  2. Dockerfiles and Docker Compose Configuration
  3. GitHub Actions Configuration and CI/CD Workflow
  4. Deploying to Koyeb
  5. Conclusion

Prerequisites

Before you begin, ensure you have the following:

  • A full stack application ready for deployment, with Dockerfile(s) and a docker-compose.yml configured to run your services locally.
  • A Koyeb account — you can sign up for free at here.
  • Basic familiarity with Docker and Docker Compose, as this deployment will rely on these tools to containerize and orchestrate your app.
  • A GitHub account with admin access to your repository so you can set up GitHub Actions workflows.
  • A Koyeb API token, which you will generate from your Koyeb dashboard and add as a secret in your GitHub repository to enable automated deployments.

Dockerfiles and Docker Compose Configuration

Backend Dockerfile

FROM python:3.12-slim

WORKDIR /app

COPY ./requirements.txt /app/

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080

CMD ["uvicorn", "main:app", "--port", "8080", "--host", "0.0.0.0"]
Enter fullscreen mode Exit fullscreen mode

This Dockerfile sets up the backend environment using a lightweight Python 3.12 slim image. The key steps are:

  • Sets the working directory to /app inside the container.
  • Copies requirements.txt and installs Python dependencies without caching to reduce image size.
  • Copies the backend source code into the container.
  • Exposes port 8080 to allow incoming connections.
  • Runs the FastAPI application using Uvicorn, listening on all network interfaces (0.0.0.0) and port 8080.

Frontend Dockerfile

FROM node:22-alpine

WORKDIR /app

COPY ./package*.json /app/

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"]
Enter fullscreen mode Exit fullscreen mode

For the frontend, a minimal Node.js Alpine image is used to keep the container small and fast. This Dockerfile:

  • Sets /app as the working directory.
  • Copies package files and installs dependencies via npm install.
  • Copies the full frontend source code into the container.
  • Exposes port 3000 to serve the frontend application.
  • Runs the frontend in development mode, binding to all interfaces on port 3000.

Docker Compose File

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - backend
  backend:
    build: ./backend
    ports:
      - "8080:8080"
Enter fullscreen mode Exit fullscreen mode

The docker-compose.yml orchestrates the two services — backend and frontend — allowing them to run together easily:

  • The backend service builds from the ./backend directory and exposes port 8080.
  • The frontend service builds from ./frontend, exposes port 3000, and depends on the backend to ensure proper startup order.
  • This setup enables the frontend to communicate with the backend seamlessly during development and deployment.

Dockerfile.koyeb (Main Deployment File)

FROM koyeb/docker-compose

COPY . /app
Enter fullscreen mode Exit fullscreen mode

This file is the core of your deployment on Koyeb. It uses the official Koyeb Docker Compose image, which is pre-configured with Docker Compose for multi-service apps. The key points:

  • Copies the entire project into /app inside the container.
  • When deployed on Koyeb, this image automatically runs the docker-compose.yml in /app.
  • This approach simplifies deployment by handling the orchestration of both backend and frontend services with a single command on Koyeb’s platform.

GitHub Actions CI/CD Configuration

Obtaining the Koyeb API Token

Before the CI/CD pipeline can deploy your app to Koyeb, you need a Koyeb API token. This token authorizes GitHub Actions to interact with your Koyeb account and manage deployments securely.

How to get your Koyeb API token:

  1. Log in to your Koyeb dashboard.
  2. Navigate to Account Settings or API Tokens section.
  3. Generate a new API token with appropriate permissions for deployment.
  4. Copy the token and add it as a secret in your GitHub repository settings under Settings > Secrets and variables > Actions > New repository secret with the name KOYEB_API_TOKEN.

Note: If your Koyeb account is banned or inaccessible, you will not be able to generate a token. In that case, consider contacting Koyeb support or using an alternative deployment provider that suits your needs.

GitHub Actions Workflow Explained

Below is the GitHub Actions Workflow YAML for building and deploying your full stack app to Koyeb using Docker Compose. Ensure you place this file in the .github/workflows/ directory.

name: github-actions-docker-compose-koyeb

on:
  push:
    branches:
      - main

jobs:
  frontend:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repository Code
        uses: actions/checkout@v2

      - name: Install and configure the Koyeb CLI
        uses: koyeb-community/koyeb-actions@v2
        with:
          api_token: "${{secrets.KOYEB_API_TOKEN}}"

      - name: Build and deploy the application to Koyeb
        uses: koyeb/action-git-deploy@v1
        with:
          app-name: glowberry-tax-structure-simulator-gha-docker-compose-koyeb
          service-name: glowberry-tax-structure-simulator-gha-docker-compose-koyeb
          service-instance-type: free
          git-builder: docker
          git-docker-dockerfile: Dockerfile.koyeb
          service-env: PORT=3000
          service-ports: "3000:http"
          service-routes: "/:3000"
          privileged: true
Enter fullscreen mode Exit fullscreen mode

Step-by-step Breakdown

  • Workflow Trigger
  on:
    push:
      branches:
        - main
Enter fullscreen mode Exit fullscreen mode

The workflow triggers whenever you push changes to the main branch, ensuring that your deployment stays up to date with the latest code.

  • Job Environment
  jobs:
    frontend:
      runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode

The job runs on the latest stable Ubuntu environment hosted by GitHub Actions.

  • Step 1: Checkout Code
  - name: Checkout Repository Code
    uses: actions/checkout@v2
Enter fullscreen mode Exit fullscreen mode

This step checks out your repository code so the workflow can access your Dockerfiles and source code.

  • Step 2: Install and Configure Koyeb CLI
  - name: Install and configure the Koyeb CLI
    uses: koyeb-community/koyeb-actions@v2
    with:
      api_token: "${{secrets.KOYEB_API_TOKEN}}"
Enter fullscreen mode Exit fullscreen mode

This action installs the Koyeb CLI tool and authenticates it with your API token stored securely in GitHub Secrets. This allows subsequent commands to interact with your Koyeb account.

  • Step 3: Build and Deploy the Application to Koyeb — Detailed Explanation

    - name: Build and deploy the application to Koyeb
      uses: koyeb/action-git-deploy@v1
      with:
        app-name: glowberry-tax-structure-simulator-gha-docker-compose-koyeb
        service-name: glowberry-tax-structure-simulator-gha-docker-compose-koyeb
        service-instance-type: free
        git-builder: docker
        git-docker-dockerfile: Dockerfile.koyeb
        service-env: PORT=3000
        service-ports: "3000:http"
        service-routes: "/:3000"
        privileged: true
    
    • app-name: The unique name assigned to your application on Koyeb, used to identify it in the platform.
    • service-name: The name of the specific service instance running your app within the application, often the same as app-name.
    • service-instance-type: The tier or resource size allocated for the service instance. Commonly set to free for small/test deployments.
    • git-builder: Specifies the build system to use, here docker, which means building Docker images from Dockerfiles.
    • git-docker-dockerfile: The Dockerfile path used as the build entry point. Dockerfile.koyeb orchestrates the build using the docker-compose setup.
    • service-env: Environment variables to set inside the running container. Here, PORT=3000 configures the app’s listening port.
    • service-ports: Maps container ports to protocols for exposure. "3000:http" exposes port 3000 over HTTP.
    • service-routes: Defines URL routing rules. "/:3000" routes root requests / to port 3000 inside the container.
    • privileged: Boolean flag to enable privileged mode (true), required for Docker-in-Docker or Docker Compose usage inside the container.

Deploying to Koyeb

Once the CI/CD pipeline is configured and your GitHub repository contains all the necessary files (Dockerfiles, docker-compose.yml, Dockerfile.koyeb, and the GitHub Actions workflow), deployment to Koyeb becomes a seamless process.

1. Push to GitHub

With everything in place, initiate a deployment by pushing your code to the main branch (or the branch specified in the workflow's on.push.branches section):

git add .
git commit -m "Deploy full stack app to Koyeb using GitHub Actions"
git push origin main
Enter fullscreen mode Exit fullscreen mode

Each push to the main branch will automatically trigger a new GitHub Actions workflow run.

2. Monitor the Deployment via GitHub Actions

After pushing, navigate to your GitHub repository in the browser and:

  • Click on the Actions tab.
  • Locate the latest workflow run at the top of the list.
  • Click into the run to see the job steps executing in real-time.
  • Ensure all steps complete successfully, especially the Build and deploy the application to Koyeb step.

You should see logs showing successful Docker image builds, Koyeb CLI usage, and confirmation that the deployment was completed.

3. Confirm on Koyeb

Once the workflow completes:

  • Go to Koyeb Dashboard.
  • Find your application by the app-name you defined in the GitHub Actions workflow.
  • Check the deployment status, logs, and access URL.
  • Your app should now be live and accessible via the assigned Koyeb subdomain or custom domain if configured.

Conclusion

With this setup, you now have a production-ready CI/CD pipeline that deploys your full stack Docker Compose application to Koyeb automatically on every push to the main branch. From defining Dockerfiles for your frontend and backend, orchestrating them with docker-compose.yml, and packaging the entire setup for Koyeb using a dedicated Dockerfile.koyeb, each part works together to ensure consistent and reliable deployments.

By leveraging GitHub Actions, you’ve eliminated the need for manual scripts or one-off deployment steps. Once your Koyeb API token is configured as a GitHub secret, the workflow handles the rest—building, pushing, and deploying—without requiring additional effort from your end.

This kind of workflow not only saves time but also enforces best practices for modern DevOps and continuous delivery. It’s a strong foundation for scaling your projects and team collaboration going forward.

Found this guide helpful? Follow EphraimX for more hands-on DevOps walkthroughs. You can also connect with me on LinkedIn or explore more of my work on my portfolio.

Top comments (0)