diff options
| author | Erg <uinarf@autistici.org> | 2024-11-28 16:42:41 +0100 | 
|---|---|---|
| committer | Erg <uinarf@autistici.org> | 2024-11-28 16:42:41 +0100 | 
| commit | d12675c238c77dc83a92eaaf8ec70a9dcf26a363 (patch) | |
| tree | 5cf27ecfab92577e574e832ea5a7824474066460 /jupyter_files | |
| parent | bf8efbce7f202f1f7650f628955fb0e42d343a1f (diff) | |
| download | fastapi_blog-private.tar.gz fastapi_blog-private.tar.bz2 fastapi_blog-private.zip | |
Add Private files :Pprivate
Diffstat (limited to 'jupyter_files')
| -rw-r--r-- | jupyter_files/Binhost_folder_structure.ipynb | 184 | ||||
| -rw-r--r-- | jupyter_files/Untitled.ipynb | 211 | ||||
| -rw-r--r-- | jupyter_files/creating_fastapi_static_blog.ipynb | 507 | 
3 files changed, 902 insertions, 0 deletions
| diff --git a/jupyter_files/Binhost_folder_structure.ipynb b/jupyter_files/Binhost_folder_structure.ipynb new file mode 100644 index 0000000..da2c7ed --- /dev/null +++ b/jupyter_files/Binhost_folder_structure.ipynb @@ -0,0 +1,184 @@ +{ + "cells": [ +  { +   "cell_type": "markdown", +   "id": "0b397cbb-8db3-40d9-a0a9-27ba0a774021", +   "metadata": {}, +   "source": [ +    "## Automatically creating new binhost directories when profile or gcc version changes" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "97c6e8be-a571-4fea-84c4-b226f03f56c6", +   "metadata": {}, +   "source": [ +    "On Gentoo Linux packages are compiled which is a time and energy consuming.\n", +    "To minimise both, I have a binhost to share compiled binaries between devices.\n", +    "The issues occurs when gcc major version changes - or a profile bump happens.\n", +    "If I do not notice either - problem. Binaries might not be compatible.\n", +    "So I wanted to automate a process of detection of those changes and automatically create subfolder for new binaries.\n", +    "When investigating I learned a neat trick. For the wise ones this is trivial, for me it was enligtening.\n", +    "Here it comes." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "2a688afd-5f24-4eab-a1c7-119d372367b5", +   "metadata": {}, +   "source": [ +    "On a regular system, emerge resides here:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "b1098db8-2f77-4b56-acef-f58113107dad", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ which emerge\n", +    "/usr/bin/emerge" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "9a1dcd6c-3f8c-455f-9d56-21e5157d0846", +   "metadata": {}, +   "source": [ +    "On my box with binhost:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "bcb9918c-20fb-49fd-baaf-b3b63356de5a", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ which emerge\n", +    "/usr/local/bin/emerge" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "a84cf35c-e744-47c9-9500-d9b8c7d3bfef", +   "metadata": {}, +   "source": [ +    "And here is $PATH:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "94092561-ae6b-41eb-831a-71bffcf30e6e", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ echo $PATH\n", +    "/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/bin:/usr/lib/llvm/18/bin:/usr/lib/llvm/17/bin" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "eb05de7d-f2f3-4cd3-acc2-769e096a3a5b", +   "metadata": {}, +   "source": [ +    "So we see that on binhost box, there is emerge that resides in location preceeding regular emerge - so it gets called first.\n", +    "It contains a shell script as follows:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "b9f78265-a1de-47eb-be21-bb66c1ed3bed", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "#!/usr/bin/env bash\n", +    "#\n", +    "# Script checking that binhost path exists before running emerge and\n", +    "# creating it if not exists\n", +    "\n", +    "PROFILE=$(eselect profile show|sed -n 2p|cut -d '/' -f4)\n", +    "GCC_VERSION=$(eselect gcc show|cut -d '-' -f5)\n", +    "BINHOST_DIR=\"/var/cache/binpkgs/${PROFILE}/gcc-${GCC_VERSION}.x/armv8a\"\n", +    "\n", +    "if [ ! -d \"${BINHOST_DIR}\" ]; then\n", +    "        echo \"${BINHOST_DIR} does not exist, creating\"\n", +    "        mkdir -p \"${BINHOST_DIR}\"\n", +    "else echo \"Binhost directory ${BINHOST_DIR} exists, proceeding with emerge ...\"\n", +    "fi\n", +    "\n", +    "PKGDIR=\"${BINHOST_DIR}\" /usr/bin/emerge \"$@\"" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "d6d085ea-b68f-4220-adaf-00223393e58e", +   "metadata": {}, +   "source": [ +    "So on every profile change subfolder to /var/cache/binpkgs gets created,\n", +    "on every gcc major version change, subfolder to /var/cache/binpkgs/<profile> gets created.\n", +    "If folder already exists script only prints a message.\n", +    "Then it calls /usr/bin/emerge - the regular emerge - with $PKGDIR variable, so binary packages are saved to the correct directory. " +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "1d464645-b7ac-4cbc-b5cc-1bd4bd976f06", +   "metadata": {}, +   "source": [ +    "This is structure of /var/cache/binpkgs:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "dee2b348-d16d-4709-a7cd-ac9424934009", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ tree -L 3 /var/cache/binpkgs/\n", +    "/var/cache/binpkgs/\n", +    "├── 17.0\n", +    "│   └── gcc-13.x\n", +    "│       └── armv8a\n", +    "└── 23.0\n", +    "    ├── gcc-13.x\n", +    "    │   └── armv8a\n", +    "    └── gcc-14.x\n", +    "        └── armv8a" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "9f8f4a71-9fd1-4678-9cb0-a580c94f4582", +   "metadata": {}, +   "source": [ +    "One less thing to worry about." +   ] +  } + ], + "metadata": { +  "kernelspec": { +   "display_name": "Python 3 (ipykernel)", +   "language": "python", +   "name": "python3" +  }, +  "language_info": { +   "codemirror_mode": { +    "name": "ipython", +    "version": 3 +   }, +   "file_extension": ".py", +   "mimetype": "text/x-python", +   "name": "python", +   "nbconvert_exporter": "python", +   "pygments_lexer": "ipython3", +   "version": "3.12.7" +  } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/jupyter_files/Untitled.ipynb b/jupyter_files/Untitled.ipynb new file mode 100644 index 0000000..feca323 --- /dev/null +++ b/jupyter_files/Untitled.ipynb @@ -0,0 +1,211 @@ +{ + "cells": [ +  { +   "cell_type": "markdown", +   "id": "78a149e6-ef3b-4b6e-a633-0c1d2eb2a7b1", +   "metadata": {}, +   "source": [ +    "# Setting up Docker for FastAPI and Jenkins CI-CD on Gentoo\n", +    "\n", +    "## Prerequisites:\n", +    "- Docker\n", +    "- Jenkins\n", +    "- FastAPI\n", +    "\n", +    "## Preparations.\n", +    "\n", +    "\n", +    "Create directory for your stuff, call it tech_project, enter it." +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "4d35806b-a9f8-43b0-82fd-b9a669295562", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ mkdir tech_project && cd tech_project" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "bdfd8575-625f-488b-aec3-73ce987086d2", +   "metadata": {}, +   "source": [ +    "Create virtual Python environment:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "42b86b21-ffa1-4d22-af97-a130b76e04d0", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ python -m venv venv" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "ba4a8e5c-5e31-4e67-9c8f-17c75b52f5e2", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "You can activate it now with:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "edaeb7c2-f19a-4a6b-bb5f-4c5fd93dcf60", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ source venv/bin/activate" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "8ebfbc06-03a0-4380-a9aa-970aafdbde75", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "(venv) - That's what should prepend your prompt now." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "bb6d9596-a6fd-4127-a626-e63851a3e38f", +   "metadata": {}, +   "source": [ +    "Create a requirements.txt file, check which versions of fastapi and pydantic you have and use those:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "a199797a-73ea-4015-b58f-e87ead2ea3f0", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "fastapi>=0.111\n", +    "pydantic>=2.7.3\n", +    "uvicorn>=0.30.1" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "25c4e82b-0685-400e-9f40-c171deefcc1f", +   "metadata": {}, +   "source": [ +    "Create a Dockerfile:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "237c5063-5370-4be7-8e29-e0e9802077e6", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "FROM python:3.12\n", +    "WORKDIR app/ .\n", +    "COPY requirements.txt .\n", +    "RUN pip install --no-cache-dir -r requirements.txt\n", +    "CMD [\"python\", \"main.py\"]" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "e2b41ff9-c9d3-4a84-bb22-0494990ef272", +   "metadata": {}, +   "source": [ +    "Start docker service (as root):" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "37b1ef3f-8ed1-4c40-9ce9-5e88843356f9", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "# rc-service docker start" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "7df0e4c5-20f2-4367-be36-e43617dab0ed", +   "metadata": {}, +   "source": [ +    "Build docker image:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "1220f1b3-1b2c-4bba-a51f-54bd1401b1ec", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ docker build -t fastapi_tech_blog ." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "36881148-8ff4-48e6-80d9-8c53a05bb90b", +   "metadata": {}, +   "source": [ +    "Watch if warn you and build:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "c962a037-75ef-4b22-b46a-f24da4994be4", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\n", +    " ---> Removed intermediate container bb903c49b10d\n", +    " ---> 2a71d86268fd\n", +    "Step 5/7 : COPY . .\n", +    " ---> 9fdcdd3d46cb\n", +    "Step 6/7 : EXPOSE 8000\n", +    " ---> Running in e63e0e7b3ccc\n", +    " ---> Removed intermediate container e63e0e7b3ccc\n", +    " ---> 72d0d9f39af7\n", +    "Step 7/7 : CMD [\"python\", \"main.py\"]\n", +    " ---> Running in b49bc996f993\n", +    " ---> Removed intermediate container b49bc996f993\n", +    " ---> fb426f2a7e15\n", +    "Successfully built fb426f2a7e15\n", +    "Successfully tagged fastapi_tech_blog:latest" +   ] +  } + ], + "metadata": { +  "kernelspec": { +   "display_name": "Python 3 (ipykernel)", +   "language": "python", +   "name": "python3" +  }, +  "language_info": { +   "codemirror_mode": { +    "name": "ipython", +    "version": 3 +   }, +   "file_extension": ".py", +   "mimetype": "text/x-python", +   "name": "python", +   "nbconvert_exporter": "python", +   "pygments_lexer": "ipython3", +   "version": "3.12.7" +  } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/jupyter_files/creating_fastapi_static_blog.ipynb b/jupyter_files/creating_fastapi_static_blog.ipynb new file mode 100644 index 0000000..b2c1851 --- /dev/null +++ b/jupyter_files/creating_fastapi_static_blog.ipynb @@ -0,0 +1,507 @@ +{ + "cells": [ +  { +   "cell_type": "markdown", +   "id": "d745c9ae-31f8-47e5-83df-42c0a39e700e", +   "metadata": {}, +   "source": [ +    "# Setting up FastAPI with Uvicorn and Openrc to serve Jupyter Notebook generated html files." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "5dec85d7-1ac2-4bdd-a5c4-40dc8ec80c1f", +   "metadata": {}, +   "source": [ +    "## Prerequisites:\n", +    "- system with openrc\n", +    "- fastapi\n", +    "- uvicorn\n", +    "- jupyter notebook (optional)\n", +    "- nginx" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "3d5a9177-1fcd-4bc6-97dd-f85c712e8a9e", +   "metadata": {}, +   "source": [ +    "## Creating FastAPI application" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "6f2751d9-cdfe-417e-8a30-8768e2fd828e", +   "metadata": {}, +   "source": [ +    "Create a directory for project and enter it:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "58fe2a08-afb0-400b-a8a2-063da88a2559", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ mkdir -p ~/Fastapi_blog/static && cd ~/Fastapi_blog" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "2ad52653-7f16-489f-8a4b-e2fd08f90d05", +   "metadata": {}, +   "source": [ +    "Create a file containing code and html template folder and template for the main page:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "27e461b5-279f-4143-ac69-5ef61b75e6af", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ touch main.py\n", +    "$ mkdir templates\n", +    "$ touch templates/main_page.html" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "9c3d9c08-81ea-43b0-bea8-8486adb06d85", +   "metadata": {}, +   "source": [ +    "main_page.html can be really minimal:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "e6a61c2c-708e-462d-b487-0ddd23b5e08a", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "<html>\n", +    "<body>\n", +    "    <h1>List of articles</h1>\n", +    "    <h2>Number of posts: {{ files|length }}</h2>\n", +    "    {% if files %}\n", +    "        {% for item in files %}\n", +    "        <a href=\"static/html/{{ item }}\">{{ item }}</a><br>\n", +    "        {% endfor %}\n", +    "    {% endif %}\n", +    "</body>\n", +    "</html>" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "b15b4217-9343-4c73-aa44-f069f6d5e776", +   "metadata": {}, +   "source": [ +    "Create basic FastAPI application serving static files at '/'. I want that as I'll be serving if from behind Nginx reverse proxy. Prefix will be set with Nginx conf file" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "90f95ae9-4079-440e-9f40-2889541cb727", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "#!/usr/bin/env python\n", +    "\n", +    "\"\"\"\n", +    "FastAPI site serving static html files.\n", +    "\"\"\"\n", +    "\n", +    "from os import listdir\n", +    "from fastapi import FastAPI\n", +    "from fastapi.staticfiles import StaticFiles\n", +    "from fastapi import FastAPI, Request\n", +    "from fastapi.staticfiles import StaticFiles\n", +    "from fastapi.templating import Jinja2Templates\n", +    "\n", +    "\n", +    "ARTICLES = 'static/html'\n", +    "templates = Jinja2Templates(directory=\"templates\")\n", +    "LIST_OF_ARTICLES = [i for i in listdir(ARTICLES) if i.endswith('.html')]\n", +    "\n", +    "app = FastAPI()\n", +    "\n", +    "app.mount(\"/\", StaticFiles(directory=\"static\", html=True), name=\"static\")\n", +    "\n", +    "\n", +    "@app.get(\"/\")\n", +    "async def main_page(request: Request):\n", +    "    \"\"\"Generate main page\"\"\"\n", +    "    return templates.TemplateResponse(\n", +    "        \"main_page.html\", {\n", +    "            \"request\": request,\n", +    "            \"files\": LIST_OF_ARTICLES,\n", +    "            \"static\": ARTICLES,\n", +    "        }\n", +    "    )\n", +    "\n", +    "\n", +    "if __name__ == \"__main__\":\n", +    "    uvicorn.run(\n", +    "            app,\n", +    "            port=8000,\n", +    "            host='127.0.0.1',\n", +    "            log_level=\"info\",\n", +    "            # uds=\"/run/tech_blog.sock\", <- uncomment if you want Unix socket\n", +    "            )" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "0def2ab2-e037-4997-b472-59784554d12f", +   "metadata": {}, +   "source": [ +    "Test run:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "7e4b78e2-9412-40a0-ad23-b1ebdc32b34d", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ uvicorn main:app --reload" +   ] +  }, +  { +   "attachments": {}, +   "cell_type": "markdown", +   "id": "1ff45780-0f1a-4f8a-a50d-7c52ad08f52d", +   "metadata": {}, +   "source": [ +    "If we try to run it as regular user with 'uds=\"/run/tech_blog.sock\"' line uncommented we should get permission denied error as we don't have rights to create files in /run.\n", +    "\n", +    "In browser, take a peek at http://localhost:8000 and you should already see something.\n", +    "\n", +    "Create a file with a test html code:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "f2cb8101-4914-494e-9c6e-222cd9cdb148", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ touch static/test.html" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "0496d679-15a2-4610-815b-9e1b57285ebf", +   "metadata": {}, +   "source": [ +    "Put this in it:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "3db82cd2-3f9f-4c74-b98b-2cf1b19dd353", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "<html>\n", +    "<body>\n", +    "\n", +    "<h1>Fun stuff comming up</h1>\n", +    "<p>Bob's your uncle!</p>\n", +    "\n", +    "</body>\n", +    "</html> " +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "fd3b37dc-e3d3-48a0-a496-7f0060bc69c0", +   "metadata": {}, +   "source": [ +    "Visit http://localhost:8000/\n", +    "You should see the main page with test article and you should be able to navigate to the article clicking the link." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "cba92c27-c741-4959-88c5-b9790de7eddf", +   "metadata": {}, +   "source": [ +    "## Jupyter side note" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "f7fefa06-9d13-4793-8bb6-3f96f2171f25", +   "metadata": {}, +   "source": [ +    "To write stuff with Jupyter Notebook start it up:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "f7eadb7f-e811-4bee-a8d7-68c68ec9f9ca", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ jupyter-notebook" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "d0ce0f2c-e633-4974-8ed4-1f4b3a021d6a", +   "metadata": {}, +   "source": [ +    "In browser a new tab with jupyter notebook should have started. Write your fun stuff. Save it. If you don't want to execute cell content convert to html with:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "7a4da315-d47b-4bec-8b17-f2cbf494f4d4", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ jupyter nbconvert --to html <path to your file>" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "80c327c4-d985-47d6-94fa-10e8e5b7d2b4", +   "metadata": {}, +   "source": [ +    "If you want to execute cell content convert with:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "54af67cd-0d26-4373-9647-8943dec2f4ab", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ jupyter nbconvert --execute --to html <path to your file>" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "f8653115-4f64-40a7-9d72-0e088a607a07", +   "metadata": {}, +   "source": [ +    "Want to change theme to dark?" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "52d5866b-813d-4ef3-9886-c775e1c67d5b", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ jupyter nbconvert --execute --to html <path to your file> --HTMLExporter.theme=dark" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "e73f69fc-6c8a-4617-90bd-a0e788b89756", +   "metadata": {}, +   "source": [ +    "Now put it in your `static` folder. It will be served by your FastAPI application." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "c56ef398-9f2e-4253-bc37-22b5926b8c7c", +   "metadata": {}, +   "source": [ +    "## Bash script" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "f37aba78-c09b-4807-ba02-c72f48b9dba5", +   "metadata": {}, +   "source": [ +    "In order to run our python script with Openrc first we need to create a Bash script:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "6f4052ac-f582-47fa-b702-34f1341dec88", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "#!/usr/bin/env bash\n", +    "\n", +    "cd /home/discordia/Fastapi_blog || exit # If your login is different, change home directory name.\n", +    "exec python main.py" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "dedf511e-f6fd-4c41-8b02-a2eb25e9604a", +   "metadata": {}, +   "source": [ +    "Save it (here as fastapi_blog.sh) as a root user to /usr/local/bin and make executable:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "7c6e7b2d-33a3-4305-917b-c24155a648f2", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "# chmod ugo+x /usr/local/bin/fastapi_blog.sh" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "1bf1a799-25b0-4008-b1d2-1a555cef79c5", +   "metadata": {}, +   "source": [ +    "## Openrc service file" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "43794484-8e10-400d-a598-d1acefd455ee", +   "metadata": {}, +   "source": [ +    "Now create a minimal service file" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "f14c6b71-3f1f-4dd8-b62d-d79721a8d6fe", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "#!/sbin/openrc-run\n", +    "\n", +    "supervisor=supervise-daemon\n", +    "command=\"/usr/local/bin/fastapi_blog.sh\"\n", +    "pidfile=\"/run/${RC_SVCNAME}.pid\"\n", +    "command_args=\"-p ${pidfile}\"\n", +    "command_background=True" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "8982eef9-a095-4b57-b0a6-5d59ac12be78", +   "metadata": {}, +   "source": [ +    "Save it as a root user in /etc/init.d and make executable:" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "6336a60f-6e8a-489b-8bc8-9b9e6f8e02fc", +   "metadata": {}, +   "source": [ +    "Save it as a root user in /etc/init.d and make executable:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "445a5744-8e71-4104-8601-ad444ca0f9c1", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "# chmod ugo+x /etc/init.d/fastapi_blog" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "0985e123-559c-4f9b-8bfc-7f75e9251756", +   "metadata": {}, +   "source": [ +    "You should be able to start/restart/stop it normally:" +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "c856613b-8541-43e4-b7e0-1d0f2a4a6d22", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "# rc-service fastapi_blog start\n", +    "# rc-service fastapi_blog restart\n", +    "# rc-service fastapi_blog stop" +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "719552bc-b736-41db-939c-6a1010ca9557", +   "metadata": {}, +   "source": [ +    "If you're using Unix socket, check for existence of /run/fastapi_blog.sock.\n", +    "Else navigate to http://127.0.0.1:8000/test.html to see page is indeed there." +   ] +  }, +  { +   "cell_type": "code", +   "execution_count": null, +   "id": "b8f408bf-120c-4adf-8e8b-3dc019a015ae", +   "metadata": {}, +   "outputs": [], +   "source": [ +    "$ ps aux | grep \"python main.py\"" +   ] +  }, +  { +   "attachments": {}, +   "cell_type": "markdown", +   "id": "13c17523-3603-4b8a-b8a2-563ae6dc27d5", +   "metadata": {}, +   "source": [ +    "You want to see only one 'python main.py'.\n", +    "At first I did not use exec which resulted in lingering processess. You don't want that.\n", +    "\n", +    "Now you can plug it in to your preffered proxy server using either a unix socket or a TCP socket." +   ] +  }, +  { +   "cell_type": "markdown", +   "id": "3134cb86-be0f-456c-b755-cd4f43ef2810", +   "metadata": {}, +   "source": [ +    "If you're using unix socket, check for existence of /run/fastapi_blog.sock, else either use lsof to see what's using port 8000 or navigate to http://127.0.0.1:8000/test.html" +   ] +  } + ], + "metadata": { +  "kernelspec": { +   "display_name": "Python 3 (ipykernel)", +   "language": "python", +   "name": "python3" +  }, +  "language_info": { +   "codemirror_mode": { +    "name": "ipython", +    "version": 3 +   }, +   "file_extension": ".py", +   "mimetype": "text/x-python", +   "name": "python", +   "nbconvert_exporter": "python", +   "pygments_lexer": "ipython3", +   "version": "3.12.7" +  } + }, + "nbformat": 4, + "nbformat_minor": 5 +} | 
