dcrx-api


Namedcrx-api JSON
Version 0.4.1 PyPI version JSON
download
home_pagehttps://github.com/scorbettUM/dcrx-api
SummaryA RESTful implementation of the DCRX Docker library.
upload_time2023-06-14 00:54:43
maintainer
docs_urlNone
authorSean Corbett
requires_python>=3.10
license
keywords pypi cicd python setup docker infra devops fastapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # dcrx-api
[![PyPI version](https://img.shields.io/pypi/v/dcrx-api?color=gre)](https://pypi.org/project/dcrx-api/)
[![License](https://img.shields.io/github/license/scorbettUM/dcrx-api)](https://github.com/scorbettUM/dcrx-api/blob/main/LICENSE)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/scorbettUM/dcrx-api/blob/main/CODE_OF_CONDUCT.md)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dcrx-api)](https://pypi.org/project/dcrx-api/)

DCRX-API is a RESTful implementation of the dcrx library, allowing you to create Docker images on request! DCRX-API extends dcrx, providing integrations with the Docker API and dcrx that allow images to be built by making REST requests.

DCRX-API also includes basic JWT authorization and user management (no-RBAC), and is intended to be deployed as an internal-facing service. dcrx also provides OpenAPI documentation to make getting started intuitive, and features integrations with SQLite, Postgres, and MySQL for storing and managing users.


# Setup and Installation

DCRX-API is available both as a Docker image and as a PyPi package. For local use, we recommend using PyPi, Python 3.10+, and a virtual environment. To install, run:

```bash
python -m venv ~/.dcrx && \
source ~/.dcrx/bin/activate && \
pip install dcrx-api
```

To get the Docker image, run:

```
docker pull adalundhe/dcrx-api:latest
```


# Getting Started

DCRX-API requires a slew of environmental variables in order to run correctly. These include:

```
DCRX_API_JOB_TIMEOUT=10m # The maximum amount of time before an image build + push job times out and is cancelled. Default is 10 minutes.

DCRX_API_MAX_MEMORY_PERCENT_USAGE=50 # The percent of system memory DCRX-API and Docker image builds created by DCRX-API can use. If exceeded, new jobs will be rejected and requests will return a 400 error. Default is 50 percent.

DCRX_API_JOB_PRUNE_INTERVAL='1s' # How often dcrx-api checks for done, failed, or cancelled jobs to remove from in-memory storage.

DCRX_API_JOB_MAX_AGE='1m'= # Time before done, failed, or cancelled jobs are pruned from in-memory storage.

DCRX_API_JOB_MAX_PENDING_WAIT=10m # The maximum amount of time a job can remain in PENDING status. Jobs that exceed this threshold are timed out and will fail.

DCRX_API_JOB_MAX_PENDING=100 # The maximum number of pending jobs that a single instance of DCRX-API allows. Default is 100.

DCRX_API_JOB_POOL_SIZE=10 # Maximum number of concurrent builds. Default is 10.

DCRX_API_JOB_WORKERS=4 # Number of workers to use per-job. Default is the number os OS threads.

DCRX_API_TOKEN_EXPIRATION='15m' # Time for JWT authorization token to expire. Default is 15 minutes.

DCRX_API_SECRET_KEY=testingthis # Initial secret used to hash user passwords.

DCRX_API_AUTH_ALGORITHM=HS256 # Algorithm to use for hashing user passwords.

DCRX_API_DATABASE_TRANSACTION_RETRIES=3 # Number of times to retry a failed transaction. Default is 3.

DCRX_API_DATABASE_TYPE=sqlite # Type of database to use. Default is sqlite and options are mysql, asyncpg, and sqlite.

DCRX_API_DATABASE_USER=admin # Username used for database connection authentication

DCRX_API_DATABASE_PASSWORD=test1234 # Password used for database connection authentrication

DCRX_API_DATABASE_NAME=dcrx # Name of database to use for storing users. Default is dcrx.

DCRX_API_DATABASE_URI=sqlite+aiosqlite:///dcrx # URL/URI of SQL database for storing users and job metadata.

DCRX_API_DATABASE_PORT=3369 # Port of SQL database for storing users and job metadata.

```

Prior to starting the server, we recommend seeding the database with an initial user. To do so, run the command:

```bash
dcrx-api database initialize --username $USERNAME --password $PASSWORD --first-name $FIRST_NAME --last-name $LAST_NAME --email $EMAIL
```

If you've chosen to run the Docker image, this step is taken care of for you, with the default user being:

```
username: admin
password: dcrxadmin1*
first-name: admin
last-name: user
email: admin@admin.com
```

Next run:

```bash
dcrx-api server run
```

and navigate to `localhost:2277/docs`, where you'll find dcrx-api's OpenAPI documentation.


# Authenticating and Building an Image

From here, we'll need to authenticate using the initial user we created above. Open the tab for `/users/login`, and for the `username` and `password` fields enter the username and password of the initial user, then click `Execute`. A `200` status response containg the initial user's username and id should return.

Before creating and pushing any images, we need to create a Registry. Navigate to the `/registry/create` tab. We'll need to provide a `registry_name` (unique shortand reference of our choosing), `registry_uri` (HTTP url to the registry), `registry_user`, and `registry_password:

```json
{
  "registry_name": "hello-world",
  "registry_uri": "https://docker.io/v1/testreg/hello-world",
  "registry_user": "testuser",
  "registry_password": "testpassword1*"
}
```

Submit the request. DCRX-API will take the information, encrypt the registry password, and store it.

Next navigate to the `/jobs/images/create` tab. As before, we'll need to fill out some data. Go ahead and copy paste the below into the input for the request body:

```json
{
  "name": "testreg/hello-world",
  "tag": "latest",
  "registry": {
    "registry_name": "hello-world"
  },
  "layers": [
    {
      "layer_type": "stage",
      "base": "python",
      "tag": "3.11-slim"
    },
    {
        "layer_type": "entrypoint",
        "command": [
            "echo",
            "Hello world!"
        ]
    }
  ]
}
```

A dcrx-api image build request requires, at-minimum, a `name`, `tag`, `registry_name`, and one or more `layer` objects, which will be processed and build in-order of appearance. Note that each layer object almost exactly corresponds to its `dcrx` call. The above corresponds exactly to:

```python

from dcrx import Image

hello_world = Image('hello-world')

hello_world.stage(
    'python',
    '3.11-slim'
).entrypoint([
    'echo',
    'Hello world!'
])
```

Go ahead and submit the request via the `Execute` button. This will start a job to build the specified image and push it to the repository specified in the request.

Note that dcrx-api doesn't wait for the image to be built, instead returning a `JobMetadata` response with a status code of `200`, including the `job_id`. Building images is time-intensive and could potentially bog down a server, so dcrx-api builds and pushes images in the background. We can use the `job_id` of a Job to make further `GET` requests to the `/jobs/images/{job_id}/get` endpoint to monitor and check how our job is progressing. If we need to cancel a job for any reason, we can simple make a `DELETE` request to `/jobs/images/{job_id}/cancel`.


# Running the Docker Image

To run the Docker image, we recommend first creating a `.env` file with the required environment variables noted above. Then run the image:

```bash
docker run -p 2277:2277 --env-file .env --privileged dcrx-api:latest
```

# Deploying via Helm

DCRX-API has a minimal helm chart to help you scale up when ready. To begin, first create a Kuberenetes secret as below:

```
kubectl create secret generic dcrx-api-secrets --from-literal="DCRX_API_SECRET_KEY=$DCRX_API_SECRET_KEY" --from-literal="DOCKER_REGISTRY_USERNAME=$DOCKER_REGISTRY_USERNAME" --from-literal="DOCKER_REGISTRY_PASSWORD=$DOCKER_REGISTRY_PASSWORD"

```

Then install the provided helm chart:

```
helm install dcrx-api helm/dcrx-api/ --values helm/dcrx-api/values.yml
```

The chart creates three replica dcrx-api pods, a LoadBalancer service, and Nginx ingress to get you up and running in your Kubernetes cluster!


# Notes and Gotchas

1. Does dcrx-api require a volume to run? - Yes. While dcrx-api builds images in-memory, Docker still (frustratingly) requires that a physical file be present in the build directory. This means that, if running dcrx-api in Docker or via Kubernetes, you will need to have a volume with the correct permissions mounted.

2. Does the dcrx-api Docker image require root? - Currently yes. The dcrx-api image is based on the latest version of Docker's `dind` image, which runs as and requires root privlidges. We're working on getting the rootless version of `dind` working though!

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/scorbettUM/dcrx-api",
    "name": "dcrx-api",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "",
    "keywords": "pypi,cicd,python,setup,docker,infra,devops,fastapi",
    "author": "Sean Corbett",
    "author_email": "sean.corbett@umontana.edu",
    "download_url": "https://files.pythonhosted.org/packages/8a/e5/094fd972f55b8e441e0945efb1aa5171f4f92fdbb626a2f452bf098b3136/dcrx-api-0.4.1.tar.gz",
    "platform": null,
    "description": "# dcrx-api\n[![PyPI version](https://img.shields.io/pypi/v/dcrx-api?color=gre)](https://pypi.org/project/dcrx-api/)\n[![License](https://img.shields.io/github/license/scorbettUM/dcrx-api)](https://github.com/scorbettUM/dcrx-api/blob/main/LICENSE)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/scorbettUM/dcrx-api/blob/main/CODE_OF_CONDUCT.md)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/dcrx-api)](https://pypi.org/project/dcrx-api/)\n\nDCRX-API is a RESTful implementation of the dcrx library, allowing you to create Docker images on request! DCRX-API extends dcrx, providing integrations with the Docker API and dcrx that allow images to be built by making REST requests.\n\nDCRX-API also includes basic JWT authorization and user management (no-RBAC), and is intended to be deployed as an internal-facing service. dcrx also provides OpenAPI documentation to make getting started intuitive, and features integrations with SQLite, Postgres, and MySQL for storing and managing users.\n\n\n# Setup and Installation\n\nDCRX-API is available both as a Docker image and as a PyPi package. For local use, we recommend using PyPi, Python 3.10+, and a virtual environment. To install, run:\n\n```bash\npython -m venv ~/.dcrx && \\\nsource ~/.dcrx/bin/activate && \\\npip install dcrx-api\n```\n\nTo get the Docker image, run:\n\n```\ndocker pull adalundhe/dcrx-api:latest\n```\n\n\n# Getting Started\n\nDCRX-API requires a slew of environmental variables in order to run correctly. These include:\n\n```\nDCRX_API_JOB_TIMEOUT=10m # The maximum amount of time before an image build + push job times out and is cancelled. Default is 10 minutes.\n\nDCRX_API_MAX_MEMORY_PERCENT_USAGE=50 # The percent of system memory DCRX-API and Docker image builds created by DCRX-API can use. If exceeded, new jobs will be rejected and requests will return a 400 error. Default is 50 percent.\n\nDCRX_API_JOB_PRUNE_INTERVAL='1s' # How often dcrx-api checks for done, failed, or cancelled jobs to remove from in-memory storage.\n\nDCRX_API_JOB_MAX_AGE='1m'= # Time before done, failed, or cancelled jobs are pruned from in-memory storage.\n\nDCRX_API_JOB_MAX_PENDING_WAIT=10m # The maximum amount of time a job can remain in PENDING status. Jobs that exceed this threshold are timed out and will fail.\n\nDCRX_API_JOB_MAX_PENDING=100 # The maximum number of pending jobs that a single instance of DCRX-API allows. Default is 100.\n\nDCRX_API_JOB_POOL_SIZE=10 # Maximum number of concurrent builds. Default is 10.\n\nDCRX_API_JOB_WORKERS=4 # Number of workers to use per-job. Default is the number os OS threads.\n\nDCRX_API_TOKEN_EXPIRATION='15m' # Time for JWT authorization token to expire. Default is 15 minutes.\n\nDCRX_API_SECRET_KEY=testingthis # Initial secret used to hash user passwords.\n\nDCRX_API_AUTH_ALGORITHM=HS256 # Algorithm to use for hashing user passwords.\n\nDCRX_API_DATABASE_TRANSACTION_RETRIES=3 # Number of times to retry a failed transaction. Default is 3.\n\nDCRX_API_DATABASE_TYPE=sqlite # Type of database to use. Default is sqlite and options are mysql, asyncpg, and sqlite.\n\nDCRX_API_DATABASE_USER=admin # Username used for database connection authentication\n\nDCRX_API_DATABASE_PASSWORD=test1234 # Password used for database connection authentrication\n\nDCRX_API_DATABASE_NAME=dcrx # Name of database to use for storing users. Default is dcrx.\n\nDCRX_API_DATABASE_URI=sqlite+aiosqlite:///dcrx # URL/URI of SQL database for storing users and job metadata.\n\nDCRX_API_DATABASE_PORT=3369 # Port of SQL database for storing users and job metadata.\n\n```\n\nPrior to starting the server, we recommend seeding the database with an initial user. To do so, run the command:\n\n```bash\ndcrx-api database initialize --username $USERNAME --password $PASSWORD --first-name $FIRST_NAME --last-name $LAST_NAME --email $EMAIL\n```\n\nIf you've chosen to run the Docker image, this step is taken care of for you, with the default user being:\n\n```\nusername: admin\npassword: dcrxadmin1*\nfirst-name: admin\nlast-name: user\nemail: admin@admin.com\n```\n\nNext run:\n\n```bash\ndcrx-api server run\n```\n\nand navigate to `localhost:2277/docs`, where you'll find dcrx-api's OpenAPI documentation.\n\n\n# Authenticating and Building an Image\n\nFrom here, we'll need to authenticate using the initial user we created above. Open the tab for `/users/login`, and for the `username` and `password` fields enter the username and password of the initial user, then click `Execute`. A `200` status response containg the initial user's username and id should return.\n\nBefore creating and pushing any images, we need to create a Registry. Navigate to the `/registry/create` tab. We'll need to provide a `registry_name` (unique shortand reference of our choosing), `registry_uri` (HTTP url to the registry), `registry_user`, and `registry_password:\n\n```json\n{\n  \"registry_name\": \"hello-world\",\n  \"registry_uri\": \"https://docker.io/v1/testreg/hello-world\",\n  \"registry_user\": \"testuser\",\n  \"registry_password\": \"testpassword1*\"\n}\n```\n\nSubmit the request. DCRX-API will take the information, encrypt the registry password, and store it.\n\nNext navigate to the `/jobs/images/create` tab. As before, we'll need to fill out some data. Go ahead and copy paste the below into the input for the request body:\n\n```json\n{\n  \"name\": \"testreg/hello-world\",\n  \"tag\": \"latest\",\n  \"registry\": {\n    \"registry_name\": \"hello-world\"\n  },\n  \"layers\": [\n    {\n      \"layer_type\": \"stage\",\n      \"base\": \"python\",\n      \"tag\": \"3.11-slim\"\n    },\n    {\n        \"layer_type\": \"entrypoint\",\n        \"command\": [\n            \"echo\",\n            \"Hello world!\"\n        ]\n    }\n  ]\n}\n```\n\nA dcrx-api image build request requires, at-minimum, a `name`, `tag`, `registry_name`, and one or more `layer` objects, which will be processed and build in-order of appearance. Note that each layer object almost exactly corresponds to its `dcrx` call. The above corresponds exactly to:\n\n```python\n\nfrom dcrx import Image\n\nhello_world = Image('hello-world')\n\nhello_world.stage(\n    'python',\n    '3.11-slim'\n).entrypoint([\n    'echo',\n    'Hello world!'\n])\n```\n\nGo ahead and submit the request via the `Execute` button. This will start a job to build the specified image and push it to the repository specified in the request.\n\nNote that dcrx-api doesn't wait for the image to be built, instead returning a `JobMetadata` response with a status code of `200`, including the `job_id`. Building images is time-intensive and could potentially bog down a server, so dcrx-api builds and pushes images in the background. We can use the `job_id` of a Job to make further `GET` requests to the `/jobs/images/{job_id}/get` endpoint to monitor and check how our job is progressing. If we need to cancel a job for any reason, we can simple make a `DELETE` request to `/jobs/images/{job_id}/cancel`.\n\n\n# Running the Docker Image\n\nTo run the Docker image, we recommend first creating a `.env` file with the required environment variables noted above. Then run the image:\n\n```bash\ndocker run -p 2277:2277 --env-file .env --privileged dcrx-api:latest\n```\n\n# Deploying via Helm\n\nDCRX-API has a minimal helm chart to help you scale up when ready. To begin, first create a Kuberenetes secret as below:\n\n```\nkubectl create secret generic dcrx-api-secrets --from-literal=\"DCRX_API_SECRET_KEY=$DCRX_API_SECRET_KEY\" --from-literal=\"DOCKER_REGISTRY_USERNAME=$DOCKER_REGISTRY_USERNAME\" --from-literal=\"DOCKER_REGISTRY_PASSWORD=$DOCKER_REGISTRY_PASSWORD\"\n\n```\n\nThen install the provided helm chart:\n\n```\nhelm install dcrx-api helm/dcrx-api/ --values helm/dcrx-api/values.yml\n```\n\nThe chart creates three replica dcrx-api pods, a LoadBalancer service, and Nginx ingress to get you up and running in your Kubernetes cluster!\n\n\n# Notes and Gotchas\n\n1. Does dcrx-api require a volume to run? - Yes. While dcrx-api builds images in-memory, Docker still (frustratingly) requires that a physical file be present in the build directory. This means that, if running dcrx-api in Docker or via Kubernetes, you will need to have a volume with the correct permissions mounted.\n\n2. Does the dcrx-api Docker image require root? - Currently yes. The dcrx-api image is based on the latest version of Docker's `dind` image, which runs as and requires root privlidges. We're working on getting the rootless version of `dind` working though!\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A RESTful implementation of the DCRX Docker library.",
    "version": "0.4.1",
    "project_urls": {
        "Homepage": "https://github.com/scorbettUM/dcrx-api"
    },
    "split_keywords": [
        "pypi",
        "cicd",
        "python",
        "setup",
        "docker",
        "infra",
        "devops",
        "fastapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7f13e8e4a0edcbba35586987628b87db7e81af9b93075f47918d24c623716f34",
                "md5": "7e7453b91432d025344ebcb07d93fe57",
                "sha256": "8aa035abe2f815f1cde68c4c3401b086125858910fbef43eda187ca2a0b58889"
            },
            "downloads": -1,
            "filename": "dcrx_api-0.4.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7e7453b91432d025344ebcb07d93fe57",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 56696,
            "upload_time": "2023-06-14T00:54:42",
            "upload_time_iso_8601": "2023-06-14T00:54:42.287331Z",
            "url": "https://files.pythonhosted.org/packages/7f/13/e8e4a0edcbba35586987628b87db7e81af9b93075f47918d24c623716f34/dcrx_api-0.4.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8ae5094fd972f55b8e441e0945efb1aa5171f4f92fdbb626a2f452bf098b3136",
                "md5": "21a2a1d639c28d6c2c7ace224ce7cdc7",
                "sha256": "49521f5e76a219365efa2e41c4fce780e95f93976a5c1615c9ac3970ef8a83a9"
            },
            "downloads": -1,
            "filename": "dcrx-api-0.4.1.tar.gz",
            "has_sig": false,
            "md5_digest": "21a2a1d639c28d6c2c7ace224ce7cdc7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 36169,
            "upload_time": "2023-06-14T00:54:43",
            "upload_time_iso_8601": "2023-06-14T00:54:43.892309Z",
            "url": "https://files.pythonhosted.org/packages/8a/e5/094fd972f55b8e441e0945efb1aa5171f4f92fdbb626a2f452bf098b3136/dcrx-api-0.4.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-14 00:54:43",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "scorbettUM",
    "github_project": "dcrx-api",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "dcrx-api"
}
        
Elapsed time: 0.09970s