Skip to content

Setup for no-downtime builds#101

Open
bhavberi wants to merge 4 commits intomasterfrom
devops
Open

Setup for no-downtime builds#101
bhavberi wants to merge 4 commits intomasterfrom
devops

Conversation

@bhavberi
Copy link
Copy Markdown
Member

No description provided.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces infrastructure changes to enable no-downtime deployments by separating shared services (MongoDB and nginx) from application services, allowing multiple application instances to run simultaneously on separate networks.

Key changes:

  • Extracted MongoDB and nginx into dedicated shared compose files (docker-compose.shared.staging.yml and docker-compose.shared.prod.yml) that can run independently
  • Added health checks to the gateway service to ensure readiness before accepting traffic
  • Configured external Docker networks (cc-staging-shared-network and cc-prod-shared-network) to enable communication between separately deployed stacks

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
nginx/app.conf.template New templated nginx configuration intended to support dynamic service naming, but lacks processing mechanism and has incorrect upstream naming patterns
docker-compose.yml Added health check configuration for gateway service in development environment
docker-compose.staging.yml Removed mongo and nginx services, added external network configuration, added health checks, removed cross-compose depends_on for mongo
docker-compose.shared.staging.yml New shared services file for staging containing mongo and nginx with their own network
docker-compose.shared.prod.yml New shared services file for production containing mongo and nginx with their own network
docker-compose.prod.yml Removed mongo and nginx services, added external network configuration, added health checks, removed cross-compose depends_on for mongo

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment on lines +2 to +14
server ${PROJECT_NAME}-auth-1;
}

upstream files {
server ${PROJECT_NAME}-files-1;
}

upstream graphql {
server ${PROJECT_NAME}-gateway-1;
}

upstream web {
server ${PROJECT_NAME}-web-1;
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The upstream server configuration uses ${PROJECT_NAME}-auth-1, but this naming pattern doesn't match how Docker Compose names services and containers.

In Docker Compose:

  • Services are addressed by their service name (e.g., auth, not ${PROJECT_NAME}-auth-1)
  • Container names default to {project}_{service}_{replica} with underscores (e.g., myproject_auth_1)
  • Even if PROJECT_NAME is defined, the pattern would be ${PROJECT_NAME}_auth_1 (underscores), not ${PROJECT_NAME}-auth-1 (hyphens)

Since all services are on the same cc-shared-network (staging) or cc-prod-shared-network (prod), nginx should reference services by their service names directly:

upstream auth {
    server auth;
}

The same issue applies to all upstream blocks (files, gateway, web).

Suggested change
server ${PROJECT_NAME}-auth-1;
}
upstream files {
server ${PROJECT_NAME}-files-1;
}
upstream graphql {
server ${PROJECT_NAME}-gateway-1;
}
upstream web {
server ${PROJECT_NAME}-web-1;
server auth;
}
upstream files {
server files;
}
upstream graphql {
server gateway;
}
upstream web {
server web;

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid suggestion

Comment on lines +19 to +30
nginx:
build: ./nginx
volumes:
- ./nginx:/etc/nginx/conf.d
environment:
- VIRTUAL_HOST=dev-clubs.iiit.ac.in
# - LETSENCRYPT_HOST=clubs.iiit.ac.in
ports:
- "9000:80"
networks:
- cc-shared-network
restart: unless-stopped
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nginx service in the shared compose file lacks a depends_on directive to ensure the application services (auth, files, gateway, web) are started before nginx. While these services are in a separate compose file, nginx will attempt to proxy to them and should wait for them to be available, or at least document that the main compose stack must be started first.

Consider adding a comment or documentation about the startup order requirement, since cross-compose depends_on doesn't work.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation can be added

Comment on lines +19 to +30
nginx:
build: ./nginx
volumes:
- ./nginx:/etc/nginx/conf.d
environment:
- VIRTUAL_HOST=clubs.iiit.ac.in
- LETSENCRYPT_HOST=clubs.iiit.ac.in
ports:
- "8000:80"
networks:
- cc-shared-network
restart: unless-stopped
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nginx service in the shared compose file lacks a depends_on directive to ensure the application services (auth, files, gateway, web) are started before nginx. While these services are in a separate compose file, nginx will attempt to proxy to them and should wait for them to be available, or at least document that the main compose stack must be started first.

Consider adding a comment or documentation about the startup order requirement, since cross-compose depends_on doesn't work.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +85
upstream auth {
server ${PROJECT_NAME}-auth-1;
}

upstream files {
server ${PROJECT_NAME}-files-1;
}

upstream graphql {
server ${PROJECT_NAME}-gateway-1;
}

upstream web {
server ${PROJECT_NAME}-web-1;
}

js_path "/etc/nginx/conf.d";
js_import http.js;

js_set $gallery_index http.gallery_index;
js_set $version http.version;

server {
listen 80;
server_name ${VIRTUAL_HOST};
client_max_body_size 100M;

location ~ ^/(login|logout|logoutCallback) {
proxy_pass http://auth$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}

location /files {
proxy_pass http://files$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}

location /graphql {
proxy_pass http://graphql$request_uri;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}

error_page 404 /custom_404.html;
location = /custom_404.html {
root /usr/share/nginx/html;
internal;
}

error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
root /usr/share/nginx/html;
internal;
}

location ~ ^/static/(.*)$ {
# expires off;
# expires 1h;
expires -1;
root /usr/share/nginx;
try_files /$1 /others/$1 /$1/ /others/$1/ =404;
}

# ignore cache frontend
location ~* (service-worker\.js)$ {
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
expires off;
proxy_no_cache 1;
}

location / {
proxy_pass http://web$request_uri;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Copy link

Copilot AI Nov 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This nginx configuration template file is introduced but there's no mechanism to process it and substitute the environment variables (${PROJECT_NAME}, ${VIRTUAL_HOST}).

The nginx Dockerfile doesn't include any envsubst command or entrypoint script to process .template files. Additionally, the shared compose files mount ./nginx:/etc/nginx/conf.d as a volume, which means any files built into the image would be overridden.

You need to either:

  1. Add an entrypoint script that runs envsubst on the template file to generate the final configuration, or
  2. Process the template during the Docker build step, or
  3. Use a different approach to handle dynamic configuration

Example entrypoint approach:

#!/bin/sh
envsubst '${PROJECT_NAME} ${VIRTUAL_HOST}' < /etc/nginx/conf.d/app.conf.template > /etc/nginx/conf.d/app.conf
nginx -g 'daemon off;'

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is to create nginx conf from git hook and conf for direct use is regardless there already (as default file)

@abhiramtilakiiit
Copy link
Copy Markdown
Contributor

@bhavberi is this pr elligible to be merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants