Skip to content

Commit

Permalink
Expose all the service ports in fly.io (#52)
Browse files Browse the repository at this point in the history
* WIP: Expose all the ports in docker via nginx

* Expose all the service ports in fly.io

* Fix end of file trailing extra newline issue
  • Loading branch information
kumaranvpl authored Nov 25, 2024
1 parent 11c643e commit e7aeab7
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 25 deletions.
96 changes: 93 additions & 3 deletions {{cookiecutter.project_slug}}/docker/content/nginx.conf.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
upstream nats_fastapi_backend {
# Enable sticky sessions with IP hash
ip_hash;


}

upstream fastapi_backend {
# Enable sticky sessions with IP hash
ip_hash;


}

upstream mesop_backend {
# Enable sticky sessions with IP hash
ip_hash;
Expand All @@ -17,10 +31,86 @@ map $fly_machine_id $sticky_action {
$FLY_MACHINE_ID "proceed"; # Cookie matches current instance
default "replay"; # Cookie exists but doesn't match - need to replay
}
{% if "nats" in cookiecutter.app_type %}
# Nats fastapi server block
server {
listen $NATS_FASTAPI_PORT;
server_name localhost;

# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";

location / {
# Handle cookie setting
if ($sticky_action = "set_cookie") {
add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/";
}

# Handle replay
if ($sticky_action = "replay") {
add_header Fly-Replay "instance=$fly_machine_id";
return 307;
}

proxy_pass http://nats_fastapi_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;

# WSGI support
proxy_set_header X-Forwarded-Host $server_name;

# Main server block
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}{%- endif %}{% if "fastapi" in cookiecutter.app_type %}
# Fastapi server block
server {
listen $FASTAPI_PORT;
server_name localhost;

# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";

location / {
# Handle cookie setting
if ($sticky_action = "set_cookie") {
add_header Set-Cookie "fly-machine-id=$FLY_MACHINE_ID; Max-Age=518400; Path=/";
}

# Handle replay
if ($sticky_action = "replay") {
add_header Fly-Replay "instance=$fly_machine_id";
return 307;
}

proxy_pass http://fastapi_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;

# WSGI support
proxy_set_header X-Forwarded-Host $server_name;

# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}{%- endif %}{% if "mesop" in cookiecutter.app_type %}
# Mesop server block
server {
listen $SERVICE_PORT;
listen $MESOP_PORT;
server_name localhost;

# Security headers
Expand Down Expand Up @@ -55,4 +145,4 @@ server {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}{%- endif %}
52 changes: 30 additions & 22 deletions {{cookiecutter.project_slug}}/docker/content/run_fastagency.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
#!/bin/bash

# Accept env variable for PORT
{% if "nats" in cookiecutter.app_type %}
NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000}
{% endif %}
{% if "fastapi" in cookiecutter.app_type %}
FASTAPI_PORT=${FASTAPI_PORT:-8008}
{% endif %}
{% if "mesop" in cookiecutter.app_type %}
export NATS_FASTAPI_PORT=${NATS_FASTAPI_PORT:-8000}
export FASTAPI_PORT=${FASTAPI_PORT:-8008}
export MESOP_PORT=${MESOP_PORT:-8888}
export SERVICE_PORT=$MESOP_PORT
{% else %}
export SERVICE_PORT=$FASTAPI_PORT
{% endif %}

# Default number of workers if not set
WORKERS=${WORKERS:-1}
echo "Number of workers: $WORKERS"
Expand All @@ -24,38 +16,54 @@ echo "Fly machine ID: $FLY_MACHINE_ID"
# Generate nginx config
for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((SERVICE_PORT + i))
PORT=$((MESOP_PORT + i))
sed -i "19i\ server 127.0.0.1:$PORT;" nginx.conf.template
done

for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((FASTAPI_PORT + i))
sed -i "12i\ server 127.0.0.1:$PORT;" nginx.conf.template
done

for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((NATS_FASTAPI_PORT + i))
sed -i "5i\ server 127.0.0.1:$PORT;" nginx.conf.template
done
envsubst '${SERVICE_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf

envsubst '${NATS_FASTAPI_PORT},${FASTAPI_PORT},${MESOP_PORT},${FLY_MACHINE_ID}' < nginx.conf.template >/etc/nginx/conf.d/default.conf
echo "Nginx config:"
cat /etc/nginx/conf.d/default.conf

# Start nginx
nginx -g "daemon off;" &
{% if "nats" in cookiecutter.app_type %}
# Run nats uvicorn server
uvicorn {{cookiecutter.project_slug}}.deployment.main_1_nats:app --host 0.0.0.0 --port $NATS_FASTAPI_PORT > /dev/stdout 2>&1 &
# Start multiple single-worker uvicorn instances on consecutive ports
for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((NATS_FASTAPI_PORT + i))
echo "Starting nats fastapi uvicorn on port $PORT"
uvicorn {{cookiecutter.project_slug}}.deployment.main_1_nats:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 &
done
{% endif %}
{% if cookiecutter.app_type == "fastapi" %}
{% if "fastapi" in cookiecutter.app_type %}
# Run uvicorn server
# Start multiple single-worker uvicorn instances on consecutive ports
for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((SERVICE_PORT + i))
echo "Starting gunicorn on port $PORT"
uvicorn {{cookiecutter.project_slug}}.deployment.main_1_fastapi:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 &
PORT=$((FASTAPI_PORT + i))
echo "Starting fastapi uvicorn on port $PORT"
uvicorn {{cookiecutter.project_slug}}.deployment.main{% if "nats" in cookiecutter.app_type %}_2_fastapi{% elif "fastapi" in cookiecutter.app_type %}_1_fastapi{% endif %}:app --workers=1 --host 0.0.0.0 --port $PORT > /dev/stdout 2>&1 &
done
{% else %}
# Run uvicorn server
uvicorn {{cookiecutter.project_slug}}.deployment.main_{% if "nats" in cookiecutter.app_type %}2_fastapi{% elif "fastapi" in cookiecutter.app_type %}1_fastapi{% endif %}:app --host 0.0.0.0 --port $FASTAPI_PORT > /dev/stdout 2>&1 &
{% endif %}
{% if "mesop" in cookiecutter.app_type %}
# Run gunicorn server
# Start multiple single-worker gunicorn instances on consecutive ports
for ((i=1; i<$WORKERS+1; i++))
do
PORT=$((SERVICE_PORT + i))
PORT=$((MESOP_PORT + i))
echo "Starting gunicorn on port $PORT"
gunicorn --workers=1 {{cookiecutter.project_slug}}.deployment.main{% if "nats" in cookiecutter.app_type %}_3_mesop{% elif "fastapi" in cookiecutter.app_type %}_2_mesop{% endif %}:app --bind 0.0.0.0:$PORT > /dev/stdout 2>&1 &
done
Expand Down
40 changes: 40 additions & 0 deletions {{cookiecutter.project_slug}}/fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,43 @@ primary_region = 'ams'
memory = '1gb'
cpu_kind = 'shared'
cpus = 1
{% if "nats" in cookiecutter.app_type %}
[[services]]
http_checks = []
internal_port = 8000
processes = ["app"]
protocol = "tcp"
script_checks = []

[services.concurrency]
type = "connections"

[[services.ports]]
handlers = ["tls", "http"]
port = 8000{%- endif %}{% if "fastapi" in cookiecutter.app_type %}
[[services]]
http_checks = []
internal_port = 8008
processes = ["app"]
protocol = "tcp"
script_checks = []

[services.concurrency]
type = "connections"

[[services.ports]]
handlers = ["tls", "http"]
port = 8008{%- endif %}{% if "mesop" in cookiecutter.app_type %}
[[services]]
http_checks = []
internal_port = 8888
processes = ["app"]
protocol = "tcp"
script_checks = []

[services.concurrency]
type = "connections"

[[services.ports]]
handlers = ["tls", "http"]
port = 8888{%- endif %}

0 comments on commit e7aeab7

Please sign in to comment.