commit 6918c077fdbe472333a77bfe3fa3e2da1b3f6f9e Author: Daniel Tam Date: Sun Mar 31 14:00:53 2024 -0500 initial deployment diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2d396e3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,165 @@ +.devcontainer/ +.github/ +*.pem +test/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2d396e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,165 @@ +.devcontainer/ +.github/ +*.pem +test/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fb3a4bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.12-slim-bookworm + +WORKDIR /app + +COPY . . + +RUN pip install -r requirements.txt + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0"] \ No newline at end of file diff --git a/host/docker-compose-template.yaml b/host/docker-compose-template.yaml new file mode 100644 index 0000000..f1a2c2e --- /dev/null +++ b/host/docker-compose-template.yaml @@ -0,0 +1,13 @@ +version: '3.8' + +services: + interview-buddy-api: + container_name: interview-buddy-api + image: {{image}} + environment: + {{#env}} + - {{key}}={{value}} + {{/env}} + ports: + - "8188:8000" + restart: unless-stopped \ No newline at end of file diff --git a/host/pull-deploy-api.sh b/host/pull-deploy-api.sh new file mode 100644 index 0000000..2b2bad2 --- /dev/null +++ b/host/pull-deploy-api.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Login +aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 891377299307.dkr.ecr.us-east-1.amazonaws.com + +# Stop current running +docker stop interview-buddy-api + +# Pull latest +docker compose pull + +# Start newest +docker compose -f docker-compose-api.yaml up -d \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..489950f --- /dev/null +++ b/main.py @@ -0,0 +1,58 @@ +from fastapi import FastAPI +from pydantic import BaseModel +import paramiko +import pystache + +app = FastAPI() +ssh_client = paramiko.SSHClient() + +deploy_script = 'pull-deploy-api.sh' +docker_compose_template = 'docker-compose-template.yaml' +docker_compose_file = 'docker-compose-api.yaml' +source = 'host' +destination = '/home/daniel' + +ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + +class Deployment(BaseModel): + image: str + env: list + +@app.post("/deploy") +async def deploy_image(deploy: Deployment): + + # Setup for moustache templating + template = "" + new_env = [] + for item in deploy.env: + for key, value in item.items(): + temp = {"key": key, "value": value} + new_env.append(temp) + + # Overwrite existing model + deploy.env = new_env + + # Read template and render + with open(f'{source}/{docker_compose_template}', 'r') as f: + template = pystache.render(f.read(), deploy) + + # Write rendered template to disk + with open(f'{source}/{docker_compose_file}', 'w') as f: + f.write(template) + + # Connect to host ststem + ssh_client.connect('192.168.40.22', username='daniel', key_filename='server.pem') + + # Copy files over + ftp_client = ssh_client.open_sftp() + ftp_client.put(f'{source}/{deploy_script}', f'{destination}/{deploy_script}') + ftp_client.put(f'{source}/{docker_compose_file}', f'{destination}/{docker_compose_file}') + ftp_client.close() + + # Execute files + stdin,stdout,stderr = ssh_client.exec_command(f'chmod +x {destination}/{deploy_script} && bash {destination}/{deploy_script}') + + # Debug out + print(stdout.readlines()) + + return {} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..d5aa125 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,27 @@ +annotated-types==0.6.0 +anyio==4.3.0 +bcrypt==4.1.2 +cffi==1.16.0 +click==8.1.7 +cryptography==42.0.5 +fastapi==0.110.0 +h11==0.14.0 +httptools==0.6.1 +idna==3.6 +paramiko==3.4.0 +pycparser==2.22 +pydantic==2.6.4 +pydantic_core==2.16.3 +PyNaCl==1.5.0 +pystache==0.6.5 +python-dotenv==1.0.1 +PyYAML==6.0.1 +setuptools==69.0.2 +sniffio==1.3.1 +starlette==0.36.3 +typing_extensions==4.10.0 +uvicorn==0.29.0 +uvloop==0.19.0 +watchfiles==0.21.0 +websockets==12.0 +wheel==0.42.0