Deployment of multi container app using docker-compose.yaml file

I’m reaching out to the community for assistance with deploying a multi-container application on Koyeb using a docker-compose.yaml file.

Application Context:

My docker-compose.yaml file includes the following services:

    • postgres on port 5432
    • maildev on port 1080
    • adminer on port 8080
    • api on port 3000

The api service is set up to wait for the postgres instance to be ready for 15 seconds before starting.

I’ve created a Dockerfile.koyeb and enabled the privilege flag on the Koyeb dashboard.

Dockerfile.koyeb:

FROM koyeb/docker-compose

# Set the working directory inside the container
WORKDIR /motac-apis

# Copy everything from the current directory on the host into /motac-apis in the container
COPY . /motac-apis/

# Run Docker Compose using the compose file in /motac-apis
CMD ["docker-compose", "-f", "/motac-apis/docker-compose.yaml", "up"]

docker-compose.yaml file:

services:
  postgres:
    image: postgres:16.3-alpine
    ports:
      - ${DATABASE_PORT}:5432
    volumes:
      - boilerplate-db:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${DATABASE_USERNAME}
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      POSTGRES_DB: ${DATABASE_NAME}

  maildev:
    build:
      context: .
      dockerfile: maildev.Dockerfile
    ports:
      - ${MAIL_CLIENT_PORT}:1080
      - ${MAIL_PORT}:1025

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

  api:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - ${APP_PORT}:${APP_PORT}
  
volumes:
  boilerplate-db:

I’m encountering the following error during deployment:

TCP health check failed on port 3000. Retrying...
09/02/2024, 12:38:00 PM  
stdout  
65b8c826  
#13 CANCELED
time="2024-09-02T07:37:10Z" level=warning msg="current commit information was not captured by the build" error="git was not found in the system: exec: \"git\": executable file not found in $PATH"

logs:

Has anyone encountered a similar issue or have any suggestions for troubleshooting this? Any help or insights would be greatly appreciated as I’m currently blocked.

Thank you in advance!

Hello,

I’m not sure to understand what is going on.
It seems the issue is your API doesn’t answer on the port 3000, so the healthcheck is failing. However, I’m not sure to understand where the message “git was not found” is from.

Could you share a public github repository to replicate the issue?

Thanks Julien,

I have resolved the git warning my adding the following line in my Dockerfile.koyeb:

# Install Git
RUN apk add --no-cache git

Port for my api is set to 3000 in my env variables and it works fine for me locally.

Just a heads up, I have also tried to update the port to 8000, then the error changes to:

#13 [api  5/16] RUN cd /tmp/app && npm install
TCP health check failed on port 8000. Retrying...
canceled
#13 CANCELED
Instance stopped

You can look into this repo for reference which is quite similar but the koyeb file is missing in this repo:

For the Dockerfile.koyeb you can see my previous comment where I shared its content.

Thanks!

As you see the error it fails on:

#13 [api  5/16] RUN cd /tmp/app && npm install

Do you think this is a memory-related issue as for now I am using the free mode of koyeb.

All the error messages that I shared till now are related to API services.

So I thought to test the reset of services by commenting on the API service in the docker-compose.yaml file.

Based on the logs: postgres, maildev, and adminer are successfully created and started for a moment.

Then stopped gracefully in the next moment:

Is there anything related to the free version of koyeb ?

It might be that you don’t have enough ram, but without a way to reproduce easily I won’t be able to debug and tell.

Can you try to increase the grace period of the healthcheck? By default it is set to 30 seconds. Since your service takes a while to listen to port 3000, maybe set it to 1 or 2 minutes?

Just forget the Health check issue as I have already attempted to deploy by updating the grace period and interval to 120 seconds. This help me to proceed further as the time for the health check is increased.

I know that I can skip the health checks on the paid version as well.

Pending issue:

Postgres service received a fast shutdown request and the service was stopped. Here is the screenshot of the logs:

Additionally, my hardware specifications on the free instance are:

  • 0.1 vCPU
  • 512MB RAM
  • 2000MB Disk

I have searched over internet and found that the minimum hardware specifications required for PostgreSQL instances are:

  • 1GHZ Dual Core processor
  • 2GB of memory
  • 2GB of disk space

Questions:
What could be causing this issue?
Could this be related to memory limitations? If so, will upgrading my plan resolve the issue? Please provide clarity so I can decide whether to upgrade my plan or explore alternative solutions.

Hello,

It is hard for me to tell you whether it’s a RAM issue or not without having an easy way to replicate your setup on a more powerful machine.

I can definitely try to run your project on a more powerful instance and tell you whether it’s working or not, but I need you to provie me with a complete GitHub repository, containing all the dockerfiles necessary, a list of the environment variables to set, and so on. I afraid I won’t be able to spend hours to setup a project :confused:

I have shared details over email.
Please take a look and let me know if you need more information from me. Thanks!

Hello,

I could make your application work with the following:

  1. Add Dockerfile.koyeb with the following content:
FROM koyeb/docker-compose

# Set the working directory inside the container
WORKDIR /motac-apis

# Copy everything from the current directory on the host into /motac-apis in the container
COPY . /motac-apis/

# Run Docker Compose using the compose file in /motac-apis
CMD ["docker-compose", "-f", "/motac-apis/docker-compose.yaml", "up"]
  • Use a large instance (I haven’t tried a smaller instance)
  • Set the builder to Dockerfile
  • Set the Dockerfile location to ./Dockerfile.koyeb
  • Set the privileged flag
  • Add all the environment variables you gave me by email
  • In the section expose ports of your service settings, expose the port 3000
  • In the health checks section of your service settings, add a grace period of 300

After a few minutes, the Nest API is successfully started and accessible.

However, please be cautious with your setup.

On Koyeb, by default, instances have ephemeral storage. It means that if you perform a new deployment of you service, or if we move your service on another physical machine for maintenance purpose, you will lose all your PostgreSQL data.

For this reason, I highly recommend you to use the database service we provide, instead of running the PostgreSQL in your Koyeb service.

Alternatively, if you really want to setup PostgreSQL yourself, we provide persistent storage, currently as a technical preview. To have early access, booking a call is necessary: Reclaim – A smart friend for your calendar

Also, you are using docker-compose. Your application has to be rebuilt everytime it is deployed. I suggest not to use docker compose at all, which will be more performant.

What I would do if I were you:

  • create a managed PostgreSQL database on Koyeb
  • for your API, create a “git” project, provide the URL of your repository, using hte “Docker” builder. This way, Koyeb will build your application. In case of new deployment (because of maintenance for example), your application doesn’t have to be rebuilt, it just has to be deployed. The instance type to use depends on the perf you need for your API.
  • create other “docker” services for maildev and adminer. For these, nano instances should be more than enough.

Best,

Thanks Julien for your support. :slightly_smiling_face: