Initial Setup - API
This guide provides comprehensive instructions for setting up the API service for the first time, including server configuration, Nginx reverse proxy setup with path-based routing, and environment configuration.
Prerequisites
Before beginning the setup process, ensure you have:
- Virtual Machine: 1 VM with a public IP address
- Security Group Configuration: Ports 22 (SSH), 80 (HTTP), and 443 (HTTPS) must be open
- SSL Certificates: Valid SSL certificate files (certificate.crt and private.key)
- Domain Name: Domain name configured to point to the VM's public IP
- GitHub Repository Access: Access to configure secret environments
- Docker Knowledge: Basic understanding of Docker and Docker Compose
- API Service Information: Container name, internal port, and URL path prefix for the API service
Step 1: Server Preparation
1.1 Connect to the Server
SSH into your virtual machine using your credentials:
ssh user@your-server-ip
1.2 Install Docker Engine
Install Docker Engine on Ubuntu by following the official Docker documentation:
# Visit and follow instructions from:
# https://docs.docker.com/engine/install/ubuntu/
For Ubuntu, you can use the convenience script:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
After adding your user to the docker group, log out and log back in for the changes to take effect.
1.3 Verify Docker Installation
Verify that Docker is installed correctly:
docker --version
docker compose version
Step 2: Nginx Reverse Proxy Setup
The API service will be served through an Nginx reverse proxy container to handle SSL termination and path-based routing.
2.1 Create Nginx Directory Structure
Create the necessary directory structure for Nginx configuration:
mkdir -p nginx/certs
cd nginx
2.2 Add SSL Certificates
Place your SSL certificate files in the certs directory:
# Copy your SSL certificate files
cp /path/to/your/certificate.crt ./certs/certificate.crt
cp /path/to/your/private.key ./certs/private.key
# Set appropriate permissions
chmod 644 ./certs/certificate.crt
chmod 600 ./certs/private.key
Ensure that private key files have restricted permissions (600) to prevent unauthorized access.
2.3 Create Docker Compose File
Create a docker-compose.yaml or compose.yaml file with the following configuration:
services:
nginx:
image: nginx:1.25-alpine
container_name: nginx-api
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./certs/certificate.crt:/etc/nginx/certs/certificate.crt:ro
- ./certs/private.key:/etc/nginx/certs/private.key:ro
networks:
- sbmcrm-network
healthcheck:
test: ["CMD", "nginx", "-t"]
interval: 30s
timeout: 10s
retries: 3
networks:
sbmcrm-network:
external: true
The sbmcrm-network must be created before starting the containers. Create it with:
docker network create sbmcrm-network
2.4 Create Nginx Configuration
Create an nginx.conf file with the following configuration. This configuration includes path-based routing, which is essential for API services:
# Upstream configuration for API service
upstream api-service {
server api-container:8080;
}
# HTTP (Port 80) Server Block - Redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name api.example.com;
server_tokens off;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS (Port 443) Server Block
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
# Client upload size limit
client_max_body_size 500m;
# SSL Certificate Configuration
ssl_certificate /etc/nginx/certs/certificate.crt;
ssl_certificate_key /etc/nginx/certs/private.key;
# Recommended TLS Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
ssl_session_tickets off;
# Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# API Location Block with Path Stripping
# This location block handles requests to /api/v1/ and strips the prefix
location /api/v1/ {
resolver 127.0.0.11 valid=30s;
# Strip the /api/v1/ prefix before proxying
rewrite ^/api/v1/(.*)$ /$1 break;
# Proxy to the API service upstream
proxy_pass http://api-service;
# HTTP Version and WebSocket Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
# Forward Client Information
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
# Cookie Forwarding
proxy_pass_header Set-Cookie;
proxy_set_header Cookie $http_cookie;
# Timeout Settings
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
send_timeout 300s;
# Cache Bypass for WebSocket
proxy_cache_bypass $http_upgrade;
}
# Health Check Endpoint (optional)
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
Replace the following placeholders in the configuration:
api.example.com: Your actual domain nameapi-service: The upstream name (can be any identifier)api-container: The Docker container name for the API service8080: The internal port the API service listens on (adjust if different)/api/v1/: The URL path prefix for your API (adjust based on your API structure)
The rewrite ^/api/v1/(.*)$ /$1 break; directive strips the /api/v1/ prefix from the request before forwarding it to the backend. This allows your API to receive requests without the path prefix, while external clients access it with the prefix.
2.5 Start Nginx Container
Start the Nginx reverse proxy:
docker compose up -d
Verify that the container is running:
docker ps
docker logs nginx-api
2.6 Test Nginx Configuration
Test the Nginx configuration for syntax errors:
docker exec nginx-api nginx -t
Step 3: Configure Secret Environments
Configure the required secret environment variables in your GitHub repository.
3.1 Access GitHub Repository Settings
- Navigate to your GitHub repository
- Click on Settings in the repository menu
- Navigate to Environments in the left sidebar
3.2 Configure Environment Secrets
Create or update the environment (e.g., staging, production) and add the following secrets:
- Database Connection Strings: PostgreSQL connection details
- Redis Connection Strings: Redis cache connection details
- JWT Secrets: Authentication token secrets
- API Keys: External service API keys
- Encryption Keys: Data encryption keys
- Third-party Service Credentials: Any required service credentials (payment gateways, SMS services, etc.)
The exact list of required secrets depends on your API configuration. Common secrets include:
DATABASE_URL: PostgreSQL connection stringREDIS_URL: Redis connection stringJWT_SECRET: JWT token signing secretENCRYPTION_KEY: Data encryption keyAPI_KEYS: External service API keys
3.3 Verify Secret Configuration
Ensure all required secrets are properly configured and accessible to your CI/CD pipeline.
Step 4: Adding Additional API Services
When you need to add additional API modules or services to the same server, you can extend the Nginx configuration:
4.1 Add New Upstream
Add a new upstream block for the additional service:
upstream new-api-service {
server new-api-container:8080;
}
4.2 Add New Location Block
Add a new location block within the HTTPS server block:
location /api/v2/ {
resolver 127.0.0.11 valid=30s;
rewrite ^/api/v2/(.*)$ /$1 break;
proxy_pass http://new-api-service;
# ... (same proxy settings as above)
}
4.3 Reload Nginx
After making changes, reload Nginx configuration:
docker exec nginx-api nginx -s reload
Or restart the container:
cd nginx
docker compose restart
Step 5: Verify Setup
5.1 Check Container Status
Verify all containers are running:
docker ps
You should see:
nginx-apicontainer running- API service container(s) running (if already deployed)
5.2 Test HTTPS Access
Test access to the API via HTTPS:
# Test the API endpoint
curl -I https://api.example.com/api/v1/health
# Test with a sample request
curl -X GET https://api.example.com/api/v1/endpoint
5.3 Verify Path Routing
Verify that path-based routing works correctly:
# This should route to your API service
curl https://api.example.com/api/v1/users
# Verify the path is correctly stripped
# Check API logs to confirm the request arrives without /api/v1/ prefix
5.4 Verify SSL Certificate
Verify that SSL is properly configured:
openssl s_client -connect api.example.com:443 -servername api.example.com
5.5 Check Nginx Logs
Monitor Nginx logs for any errors:
docker logs -f nginx-api
Troubleshooting
Common Issues
Nginx container fails to start
- Verify Docker network exists:
docker network ls - Check if ports 80 and 443 are already in use:
sudo netstat -tulpn | grep -E ':(80|443)' - Verify SSL certificate paths and permissions
502 Bad Gateway errors
- Verify the API container is running:
docker ps - Check if the container name and port in nginx.conf match the actual service
- Verify Docker network connectivity:
docker network inspect sbmcrm-network - Check API service logs:
docker logs <api-container-name>
Path routing not working
- Verify the
rewritedirective is correctly configured - Check that the location block path matches your API path prefix
- Test with
curl -vto see the full request/response headers - Verify the API service is receiving requests without the path prefix
SSL certificate errors
- Ensure certificate files are in the correct format (PEM)
- Verify certificate and key match:
openssl x509 -noout -modulus -in certs/certificate.crt | openssl md5andopenssl rsa -noout -modulus -in certs/private.key | openssl md5 - Check certificate expiration:
openssl x509 -in certs/certificate.crt -noout -dates
Connection timeouts
- Verify firewall rules allow traffic on ports 80 and 443
- Check security group settings in your cloud provider
- Verify domain DNS points to the correct IP address
- Check API service health:
docker logs <api-container-name>
CORS issues
- Ensure your API service handles CORS headers correctly
- Verify Nginx is not interfering with CORS headers
- Check browser console for specific CORS error messages
Next Steps
After completing the initial setup:
- Deploy the API Service: Follow the API Deployment Guide to deploy your first version
- Add Additional Services: Use the process described in Step 4 to add more API modules
- Configure Monitoring: Set up monitoring and logging as described in the Monitoring Setup Guide
- Review Security: Review and implement additional security measures from the SSL Security Guide