Skip to content

Commit

Permalink
Docker: Add initial Docker deployment setup (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hialus authored Mar 15, 2024
1 parent a5dbce0 commit d671a29
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 0 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build

on:
pull_request:
paths-ignore:
- 'README.md'
- 'LICENSE'
- '.github/**'
- '!.github/workflows/build.yml'
push:
branches:
- main
tags: '[0-9]+.[0-9]+.[0-9]+'
paths-ignore:
- 'README.md'
- 'LICENSE'
- '.github/**'
- '!.github/workflows/build.yml'
release:
types:
- created

jobs:
docker:
name: Build and Push Docker Image
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'ls1intum/Pyris' }}
runs-on: ubuntu-latest
steps:
- name: Compute Tag
uses: actions/github-script@v6
id: compute-tag
with:
result-encoding: string
script: |
if (context.eventName === "pull_request") {
return "pr-" + context.issue.number;
}
if (context.eventName === "release") {
return "latest";
}
if (context.eventName === "push") {
if (context.ref.startsWith("refs/tags/")) {
return context.ref.slice(10);
}
if (context.ref === "refs/heads/main") {
return "latest";
}
}
return "FALSE";
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# Build and Push to GitHub Container Registry
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
if: ${{ steps.compute-tag.outputs.result != 'FALSE' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push to GitHub Container Registry
uses: docker/build-push-action@v4
if: ${{ steps.compute-tag.outputs.result != 'FALSE' }}
with:
platforms: amd64, arm64
file: ./Dockerfile
context: .
tags: ghcr.io/ls1intum/pyris:${{ steps.compute-tag.outputs.result }}
push: true
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
#######################
# Custom rules #
#######################
application.local.yml
llm_config.local.yml


########################
# Auto-generated rules #
########################
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Dockerfile to build a container image for a Python 3.12 FastAPI application
FROM python:3.12-slim

# Set the working directory in the container
WORKDIR /app

# Copy the dependencies file to the working directory
COPY requirements.txt .

# Install any dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY app/ ./app

# Specify the command to run on container start
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
35 changes: 35 additions & 0 deletions docker/nginx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ----------------------------------------------------------------------------------------------------------------------
# Nginx base service
# ----------------------------------------------------------------------------------------------------------------------

services:
nginx:
container_name: pyris-nginx
image: nginx:1.23
pull_policy: always
volumes:
- ./nginx/timeouts.conf:/etc/nginx/conf.d/timeouts.conf:ro
- ./nginx/pyris-nginx.conf:/etc/nginx/conf.d/pyris-nginx.conf:ro
- ./nginx/pyris-server.conf:/etc/nginx/includes/pyris-server.conf:ro
- ./nginx/dhparam.pem:/etc/nginx/dhparam.pem:ro
- ./nginx/nginx_502.html:/usr/share/nginx/html/502.html:ro
- ./nginx/70-pyris-setup.sh:/docker-entrypoint.d/70-pyris-setup.sh
- ./nginx/certs/pyris-nginx+4.pem:/certs/fullchain.pem:ro
- ./nginx/certs/pyris-nginx+4-key.pem:/certs/priv_key.pem:ro
ports:
- "80:80"
- "443:443"
# expose the port to make it reachable docker internally even if the external port mapping changes
expose:
- "80"
- "443"
healthcheck:
test: service nginx status || exit 1
start_period: 60s
networks:
- pyris

networks:
pyris:
driver: "bridge"
name: pyris
2 changes: 2 additions & 0 deletions docker/nginx/70-pyris-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# disable default.conf
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled || true
28 changes: 28 additions & 0 deletions docker/nginx/certs/pyris-nginx+4-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQCuCJSHStSQd02f
j+IlQFes7pVUcYv2r0qm5qicGwPcKQf1/nmsy6k4WhE9HQV9VO9LQ4doSNp9NuYX
P/JQqdYLZYYQvxHS+fR7ofIPjirsrbQYAkG5F6imM8H7MkkueG3HGqaKD54PBmC4
BgBJDFWiF8jSNSYNKOE2L5SaYG/g3LLIkWBlhBQHgrprkio4pv5Y44+nf+hGWkSj
bkRo2+PmIsNmQrpDB2o0O7uoyswa71HE967n9K17SWZ7Hi4kP6BGUWn65P5JB10a
6kz0y8183Uzz99bx8hzxLPg6VNiJZQ+dH4M1Jn6kysKiyV4x24JsM9s6t+Vhln9E
KX5ktosdAgMBAAECggEBAJs3ddkwqWLrtOSR/H2C5G+NHsyAtPdgIfG3mTwZcBjk
03/X5gdyYUusMOHTx3ifzwjOgq9FAvFYjGDCHMlKoGfrtWWsNCZ53k6CApVTE/+h
cRVUte9yJW2Ojf0PPWvf5vEEWPKbuTnnU03ttEVyZdG66tZoprZn9m1QhHYnesEO
PMPvYMd3Oyko8MD/Rr1A/KS/rmc0yfUvgLsqF6PLxq3NKxyVD/8Tp4u9aXbPMnd2
vugVxjjvt5ubscF1Owi8EjqjVkXlw94JzLcy70XfBzsS2EvUtX/hmHgBEsViXUOQ
KGVyeFTvuReq0RvLQi1LA8vs2q6UC0ZYX75wGDfWWnUCgYEAyP6FY6xdP+N83qEM
TzAf2a33bBCcD5zbrfsvYwHwdzcAz9HBdf3TN1ZcbgfIzIWvuo+hFdjZd32E2+b7
tSGpcs21iZ3dn1aWxngNs/h94h6cNak/02iCbOsmMX9rHfKZd1ODnQyA8q0s9PQY
uWWWMUfqPse7mSYbgU0aYOVFraMCgYEA3ak3N2mTgTVsUqhNyZCJlmtafp0tsT6b
/7GKSqkl741wokM6un3wx1eo6Q95mngxOlY2xxq9OChnNSEa9ZQnzdUDtQ0YE4QD
09awTIMHNCeSqpV2n3Yv2fT3C5Ya5/WEtYGpVAtqgxwWPij8+VMOa8MVzy+/v6Hg
N1Tpww+Y8D8CgYEAhbEGeK4FuKFQRaVJ0sJn7RrSIIdLxvbHCIqzkl+P2zwyxgj3
bcxP2dcP1ABJiADESouO0kFTJS/QV5TkiC7DzyEVR1xCNeIamBjyxGrdELLbpLXX
Rn+VgW1IElR2o4zil4RtXuEaRFD8PlK+v1La/ByhqvCfz9aRJQhsK1dVaZECgYEA
jRYR0TFf89P/OLVrnapkCNwX45ND7Bc/0AY/UbpMLSfH02AbV2yl/xvqpT12Vz29
h7Ysc5qvabk9x/FkaX99vmOhUnIdKv7SONnjqS+VPDsb/XvY3zKozoA/Zp6KTa5W
Y/k9wALsLruH5NTOABw/h5PKo+9uixkLz+w6Ri/9Vp0CgYEAqfkZJe7vCOIwtIwj
Mq5knkJgR+Vq30i4jRoFU0yxIcWA1hODVBnK39+mtA++/3+r5DY5fGRTc9mMyXU/
y2N2nfSnvPMAUaRmisB7NhmvinEgymlrX+WE+7S9/+nOQADxzWSc6Hxg/ub6mTYV
k2/hv9uG1gbm2+OBP/EBOr48jz0=
-----END PRIVATE KEY-----
25 changes: 25 additions & 0 deletions docker/nginx/certs/pyris-nginx+4.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIERjCCAq6gAwIBAgIQSQ2vfdquHAQcrzbEKx46mzANBgkqhkiG9w0BAQsFADBf
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExGjAYBgNVBAsMEXJvb3RA
MWY0ZmQzNzYzNmMyMSEwHwYDVQQDDBhta2NlcnQgcm9vdEAxZjRmZDM3NjM2YzIw
HhcNMjIxMjA1MDk0NTEzWhcNMjUwMzA1MDk0NTEzWjBFMScwJQYDVQQKEx5ta2Nl
cnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxGjAYBgNVBAsMEXJvb3RAMWY0ZmQz
NzYzNmMyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArgiUh0rUkHdN
n4/iJUBXrO6VVHGL9q9KpuaonBsD3CkH9f55rMupOFoRPR0FfVTvS0OHaEjafTbm
Fz/yUKnWC2WGEL8R0vn0e6HyD44q7K20GAJBuReopjPB+zJJLnhtxxqmig+eDwZg
uAYASQxVohfI0jUmDSjhNi+UmmBv4NyyyJFgZYQUB4K6a5IqOKb+WOOPp3/oRlpE
o25EaNvj5iLDZkK6QwdqNDu7qMrMGu9RxPeu5/Ste0lmex4uJD+gRlFp+uT+SQdd
GupM9MvNfN1M8/fW8fIc8Sz4OlTYiWUPnR+DNSZ+pMrCosleMduCbDPbOrflYZZ/
RCl+ZLaLHQIDAQABo4GXMIGUMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
BgEFBQcDATAfBgNVHSMEGDAWgBSpuKALkiwfLnQmm7+JNG2bxGAIgzBMBgNVHREE
RTBDgg1hcnRlbWlzLW5naW54gg9hcnRlbWlzLmV4YW1wbGWCCWxvY2FsaG9zdIcE
fwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAYEApG8ZADQe
SsH/nqH9WpR3ZkYg0rm8pw+YquBNUdDFG2/4IQtaaxrgsvNPrEEMXfCO4vvnC0cH
6Tgay8LzFZxU9D1F06VZ9S1C7KNnYSsjgwhW7wxem1JXgauoutA8D0uHLr/2bVnz
rTShQT7gRp9SRunqDylaSkgpXlfZQRlEANrYT8Jh6LIHRjkxLh/etw7VdFA6Tywh
iQGBE/EbQcGpmqHBoMytblku0D8H+pcFHZ03AZq0FTMbByM9GekQ8HJV88epqvqJ
7pWyQPX9lr7yC6n121dPoA0ylP8D7jIBCmlFeF+QWCiRAgdeb1w+JONHMgI97IR+
9HBm6gGE+Da/TRq82w02tUN/F7NHdzqwKGx/GKLrEsdNlfP6D9iiVtfBGBoAUm+C
2t3jbQEgqYHA+mzadS75RGJsRnVdY24IHvNjEnESW6KCaSfQyMmp3trRH6JeOttU
2JeqRPjmOzNvzIcB76w1/hB2ljhimyfoxB8Gbrts+GFPRZE+AXg1mvCn
-----END CERTIFICATE-----
13 changes: 13 additions & 0 deletions docker/nginx/dhparam.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN DH PARAMETERS-----
MIICCAKCAgEAiT9FabLCTYkbfSNvenLC4q5kWMNIjCUTcYWZpt8xOlmrJQqgui9h
lKXP3hDe0J50oqYUkDQ+YS8i+GCVLzAJqXixqynLqrz/v5IWgloQMJJKlPBEl9M6
/Kh40+VyasVz7toja4qbyN12Kz1S8qLOlmxCcPmOpxGwIUG2yYSuZH9JQ724Gnji
4puFw3CXDm6aBZWBb7cpwEvHSVW5C9R+Acph7ahCby9kWpLrLsNHL73+jJiJSGcx
hig+Yie2XTTlUBHVcxlHCZu8pFXA40hLuagejmXGuVfaaoezMyU1OpfrJpsJSE2s
OxFEt01nCaEguNn7L1dr46fHWux651/UCRHR8MB0J6KEOuKDhgQ8bq+WSGlowaJM
NGhGxAlFH98D/gbOrVcRxJDpmaSFVVwO4piDT/pBDvzaS6Ll8dnoKLv8TNa2r7dG
gedlnJ2gIhU3lLLjqIwe+fmrfhlr3ybwuIiSx/efEaw65vDnOkOHeKKXtbxUAMS6
07bLIKLEw4QRwMmrLhzu2sZnFipAppXjsQ8tRa/QO4eoaEM97FKq6qONVwAA2if6
l3amSySYVDvMYpaOwQYawKTole1Kon06h8JlIr+A5W3vmraMfQZZY72HAkxuOYH0
wchOEYKU+jlmutbEdz747Ngleb5kp55CtL/PlEawEpqXWWXYBqo8mmMCAQI=
-----END DH PARAMETERS-----
27 changes: 27 additions & 0 deletions docker/nginx/nginx_502.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- ansible-managed -->
<!DOCTYPE html>
<html lang="en">
<title>Pyris Maintenance</title>
<meta http-equiv="refresh" content="5"/>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
<style>
html, body { padding: 0; margin: 0; width: 100%; height: 100%; }
* {box-sizing: border-box;}
body { text-align: center; padding: 0; background: #353d47; color: #fff; font-family: Open Sans; }
h1 { font-size: 50px; font-weight: 100; text-align: center;}
body { font-family: Open Sans; font-weight: 100; font-size: 20px; color: #fff; text-align: center; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; align-items: center;}
article { display: block; width: 700px; padding: 50px; margin: 0 auto; }
a { color: #fff; font-weight: bold;}
a:hover { text-decoration: none; }
svg { width: 75px; margin-top: 1em; }
</style>

<article>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 202.24 202.24"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Asset 3</title><g id="Layer_2" data-name="Layer 2"><g id="Capa_1" data-name="Capa 1"><path class="cls-1" d="M101.12,0A101.12,101.12,0,1,0,202.24,101.12,101.12,101.12,0,0,0,101.12,0ZM159,148.76H43.28a11.57,11.57,0,0,1-10-17.34L91.09,31.16a11.57,11.57,0,0,1,20.06,0L169,131.43a11.57,11.57,0,0,1-10,17.34Z"/><path class="cls-1" d="M101.12,36.93h0L43.27,137.21H159L101.13,36.94Zm0,88.7a7.71,7.71,0,1,1,7.71-7.71A7.71,7.71,0,0,1,101.12,125.63Zm7.71-50.13a7.56,7.56,0,0,1-.11,1.3l-3.8,22.49a3.86,3.86,0,0,1-7.61,0l-3.8-22.49a8,8,0,0,1-.11-1.3,7.71,7.71,0,1,1,15.43,0Z"/></g></g></svg>
<h1>We&rsquo;ll be back soon!</h1>
<div>
<p>We&rsquo;re performing some maintenance at the moment. Sorry for the inconvenience.</p>
<p>&mdash; Your Pyris Administrators</p>
</div>
</article>
</html>
41 changes: 41 additions & 0 deletions docker/nginx/pyris-nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Load balancing
upstream pyris {
server pyris-app:8000;
}

# Remove nginx version from HTTP response
server_tokens off;

# Rate limit for the login REST call, at most one requests per two seconds
limit_req_zone $binary_remote_addr zone=loginlimit:10m rate=30r/m;

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;

return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;

ssl_certificate /certs/fullchain.pem;
ssl_certificate_key /certs/priv_key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# TODO: dynamic dh param generation not needed here? Otherwise have to generate them somehow if not available at container entrypoint
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_ecdh_curve secp384r1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# ssl_early_data on;

include includes/pyris-server.conf;
}
32 changes: 32 additions & 0 deletions docker/nginx/pyris-server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resolver 127.0.0.11;
resolver_timeout 5s;
client_max_body_size 10m;
client_body_buffer_size 1m;

location / {
proxy_pass http://pyris;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
# proxy_set_header Early-Data $ssl_early_data;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_send_timeout 900s;
proxy_read_timeout 900s;
proxy_max_temp_file_size 0;
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
fastcgi_send_timeout 900s;
fastcgi_read_timeout 900s;
client_max_body_size 128M;
}

error_page 502 /502.html;
location /502.html {
root /usr/share/nginx/html;
internal;
}
4 changes: 4 additions & 0 deletions docker/nginx/timeouts.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
proxy_send_timeout 900s;
proxy_read_timeout 900s;
fastcgi_send_timeout 900s;
fastcgi_read_timeout 900s;
21 changes: 21 additions & 0 deletions docker/pyris-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ----------------------------------------------------------------------------------------------------------------------
# Setup for a Pyris development server.
# ----------------------------------------------------------------------------------------------------------------------

services:
pyris-app:
extends:
file: ./pyris.yml
service: pyris-app
pull_policy: never
restart: "no"
volumes:
- ../application.local.yml:/config/application.yml:ro
- ../llm_config.local.yml:/config/llm_config.yml:ro
networks:
- pyris

networks:
pyris:
driver: "bridge"
name: pyris
42 changes: 42 additions & 0 deletions docker/pyris-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ----------------------------------------------------------------------------------------------------------------------
# Setup for a Pyris production server.
# ----------------------------------------------------------------------------------------------------------------------
# It is designed to take in a lot of environment variables to take in all the configuration of the deployment.
# ----------------------------------------------------------------------------------------------------------------------

services:
pyris-app:
extends:
file: ./pyris.yml
service: pyris-app
image: ghcr.io/ls1intum/pyris:${PYRIS_DOCKER_TAG:-latest}
depends_on:
nginx:
condition: service_started
pull_policy: always
restart: unless-stopped
volumes:
- ${PYRIS_APPLICATION_YML_FILE}:/config/application.yml:ro
- ${PYRIS_LLM_CONFIG_YML_FILE}:/config/llm_config.yml:ro
networks:
- pyris

nginx:
extends:
file: ./nginx.yml
service: nginx
restart: always
volumes:
- type: bind
source: ${NGINX_PROXY_SSL_CERTIFICATE_PATH:-./nginx/certs/pyris-nginx+4.pem}
target: "/certs/fullchain.pem"
- type: bind
source: ${NGINX_PROXY_SSL_CERTIFICATE_KEY_PATH:-./nginx/certs/pyris-nginx+4-key.pem}
target: "/certs/priv_key.pem"
networks:
- pyris

networks:
pyris:
driver: "bridge"
name: pyris
Loading

0 comments on commit d671a29

Please sign in to comment.