Skip to content

Building multi-service applications

You can build applications that consist of multiple interconnected services, such as frontend and backend components.

Repository organization

Single repository approach is recommended:

  • Store all components of your application in a single repository.

  • Organize different parts (for example, frontend, backend) into separate folders.

Example structure:

/my-application

/frontend

Dockerfile

/src

...

/backend

Dockerfile

/src

...

Service communication

Services can communicate with each other in two primary ways:

  • Via internal links:

    • Each service is assigned an internal URL when deployed.
    • Services can communicate using these internal links.
    • Containers are encapsulated and can only exchange information via ports.
  • Using environment variables

    • Pass the internal URL of one service to another using environment variables (one of the available options).
    • This allows dynamic configuration without hardcoding connection details.

Frontend-backend connection example

For a typical web application with frontend and backend components:

Backend service setup

  1. Deploy the backend service first.
  2. Expose the necessary API ports.
  3. After deployment, find the internal link as follows:
    1. Click on the service name.
    2. Go to the Ports tab.
    3. Copy the Internal link.

Frontend service setup with Nginx

  1. Create an Nginx configuration template (for example, default.conf.template):
server {  
    listen 80;  
    server_name localhost;  
      
    location / {  
        root /usr/share/nginx/html;  
        index index.html;  
        try_files $uri $uri/ /index.html;  
    }  
  
    location /api/ {  
        proxy_pass http://${BACKEND_URL}/;  
        proxy_http_version 1.1;  
        proxy_set_header Upgrade $http_upgrade;  
        proxy_set_header Connection 'upgrade';  
        proxy_set_header Host $host;  
        proxy_cache_bypass $http_upgrade;  
    }  
}
  1. Configure your frontend Dockerfile to use this template:
# ... other Dockerfile instructions ...  
  
# Copy the Nginx template  
COPY default.conf.template /etc/nginx/templates/  
  
# Use envsubst to process the template  
CMD ["/bin/sh", "-c", "envsubst '${BACKEND_URL}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]

When creating the frontend service:

  1. Add an environment variable named BACKEND_URL with the value of the backend's internal link.
  2. Expose the appropriate port (typically 80 for HTTP).

Deployment order

For applications with interdependent services:

  1. Deploy independent services first (for example, databases, backend APIs).
  2. Copy the internal links of these services.
  3. Deploy dependent services (for example, frontends, middleware) with the appropriate environment variables.
  4. Test the complete application.

Important considerations

  • Services can only communicate via exposed ports.
  • Changes to service configurations require a restart to take effect.
  • For complex applications, consider using environment variables for all configuration to make services more portable.
  • The port specified in your service configuration should match the port your application listens on inside the container.