Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker image for optimade on ghcr.io #1171

Merged
merged 19 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 24 additions & 7 deletions .docker/run.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
#!/bin/bash
set -ex
#!/usr/bin/env bash
# Bash script to run upon starting the Dockerfile.
#
# Any extra parameters supplied to this script will be passed on to `uvicorn`.
# This is can be nice if using the image for development (adding `--reload` and more).
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
set -e

if [ "${MAIN}" == "main_index" ]; then
PORT=5001
else
if [ "${OPTIMADE_CONFIG_FILE}" == "/app/optimade_config.json" ]; then
echo "Using the demo config file."
echo "Set the environment variable OPTIMADE_CONFIG_FILE to override this behaviour."
echo "For more configuration options, please see https://www.optimade.org/optimade-python-tools/configuration/."
echo "Note, the variable should point to a bound path within the container."
fi

if [ -z "${OPTIMADE_LOG_LEVEL}" ]; then
export OPTIMADE_LOG_LEVEL=info
fi

if [ "${OPTIMADE_DEBUG}" == "1" ]; then
export OPTIMADE_LOG_LEVEL=debug
fi

# Determine the server to run (standard or index meta-db)
if [ -z "${MAIN}" ] || ( [ "${MAIN}" != "main_index" ] && [ "${MAIN}" != "main" ] ); then
MAIN="main"
PORT=5000
fi

uvicorn optimade.server.$MAIN:app --host 0.0.0.0 --port $PORT
uvicorn optimade.server.${MAIN}:app --host 0.0.0.0 --port 5000 --log-level ${OPTIMADE_LOG_LEVEL} "$@"
99 changes: 99 additions & 0 deletions .github/workflows/cd_container_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Build and Publish Container Image

on:
workflow_call:
inputs:
release:
description: 'Whether or not this is a release.'
default: false
required: false
type: boolean
checkout_ref:
description: 'The git ref to checkout and use as source.'
default: master
required: false
type: string

jobs:
publish_container_image:
name: Publish Container image on GH Container Registry
if: github.repository_owner == 'Materials-Consortia'
runs-on: ubuntu-latest

env:
IMAGE_NAME: optimade

steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
ref: ${{ inputs.checkout_ref }}

- name: Retrieve version
run: |
# Get current OPTIMADE version from optimade/__init__.py
regex="^__version__ = (\"|')(.*)(\"|')$"
while IFS="" read -r line || [ -n "${line}" ]; do
if [[ "${line}" =~ $regex ]]; then
VERSION="${BASH_REMATCH[2]}"
fi
done < optimade/__init__.py

echo "VERSION=${VERSION}" >> $GITHUB_ENV
echo VERSION=${VERSION}

- name: Set source ref
run: |
if [[ "${{ inputs.release }}" == "true" ]]; then
# Use tag for metadata instead of commit SHA
SOURCE_REF=v${{ env.VERSION }}
else
SOURCE_REF=$(git rev-parse HEAD)
fi

echo "SOURCE_REF=${SOURCE_REF}" >> $GITHUB_ENV
echo SOURCE_REF=${SOURCE_REF}

- name: Build image
run: |
docker build \
--file Dockerfile \
--tag "${IMAGE_NAME}" \
--label "gh_actions_runnumber=${GITHUB_RUN_ID}" \
--label "org.openctonainers.image.title=OPTIMADE" \
--label "org.opencontainers.image.description=A server implementation for serving an OPTIMADE API." \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository }}/tree/${{ env.SOURCE_REF }}" \
--label "org.opencontainers.image.documentation=https://github.com/${{ github.repository }}/blob/${{ env.SOURCE_REF }}/README.md" \
--label "org.opencontainers.image.licenses=MIT" \
--label "org.opencontainers.image.url=https://github.com/${{ github.repository }}/pkgs/container/${IMAGE_NAME}" \
--label "org.opencontainers.image.vendor=${{ github.repository_owner }}" \
--label "org.opencontainers.image.version=${{ env.VERSION }}" \
--label "org.opencontainers.image.base.name=docker.io/library/python:3.10-slim" \
.

- name: Create full image ID and tag with 'latest'
run: |
IMAGE_ID=ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME}

# Change all uppercase to lowercase
IMAGE_ID=$(echo ${IMAGE_ID} | tr '[A-Z]' '[a-z]')

echo "IMAGE_ID=${IMAGE_ID}" >> $GITHUB_ENV
echo IMAGE_ID=${IMAGE_ID}

# Tag with "latest"
docker tag ${IMAGE_NAME} ${IMAGE_ID}:latest

- name: Tag with version - if it's a release
if: inputs.release
run: docker tag ${IMAGE_NAME} ${{ env.IMAGE_ID }}:${{ env.VERSION }}

- name: Log in to registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

- name: Push image
run: |
docker image inspect ${IMAGE_NAME}
docker push --all-tags ${{ env.IMAGE_ID }}
12 changes: 12 additions & 0 deletions .github/workflows/cd_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,15 @@ jobs:
run: |
mike deploy --push --remote origin --branch gh-pages --update-aliases --config-file mkdocs.yml ${GITHUB_REF#refs/tags/v} stable
mike deploy --push --remote origin --branch gh-pages --update-aliases --config-file mkdocs.yml latest master

publish_container_image:
name: Publish container image
needs: publish
uses: ./.github/workflows/cd_container_image.yml
with:
release: true
checkout_ref: ${{ env.PUBLISH_UPDATE_BRANCH }}
secrets: inherit
permissions:
packages: write
contents: read
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ jobs:
with:
submodules: true

- name: Build the Docker images
run: docker-compose build
- name: Build the container image
run: docker build -f Dockerfile --build-arg CONFIG_FILE=.docker/docker_config.json --tag optimade .

- name: Start Docker image - server
run: |
docker-compose up optimade &
docker run --rm -d -p 3213:5000 --name optimade optimade
.github/utils/wait_for_it.sh localhost:3213 -t 120
sleep 15

Expand All @@ -119,7 +119,7 @@ jobs:

- name: Start Docker image - index server
run: |
docker-compose up optimade-index &
docker run --rm -d -p 3214:5000 --name optimade-index -e MAIN=main_index optimade
.github/utils/wait_for_it.sh localhost:3214 -t 120
sleep 15

Expand Down
25 changes: 22 additions & 3 deletions .github/workflows/ci_cd_updated_master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,28 @@ env:
GIT_USER_EMAIL: "dev@optimade.org"

jobs:
deploy-docs:
deploy_docs:
name: Deploy `latest` documentation
if: github.repository_owner == 'Materials-Consortia'
runs-on: ubuntu-latest
outputs:
release_run: ${{ steps.release_check.outputs.release_run }}

steps:
- name: Release check
id: release_check
run: |
COMMIT_MSG="$(gh api /repos/${{ github.repository}}/commits/${{ env.DEFAULT_REPO_BRANCH }} --jq '.commit.message')"
if [[ "${COMMIT_MSG}" =~ ^Release\ v.*\ -\ Changelog$ ]]; then
echo "In a release - do not run this job !"
echo "RELEASE_RUN=true" >> $GITHUB_ENV
RELEASE_RUN=true
else
echo "Not a release - update docs"
echo "RELEASE_RUN=false" >> $GITHUB_ENV
RELEASE_RUN=false
fi

echo "RELEASE_RUN=${RELEASE_RUN}" >> $GITHUB_ENV
echo "::set-output name=release_run::${RELEASE_RUN}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down Expand Up @@ -145,3 +151,16 @@ jobs:
env:
HD_OPTIMADE_CONFIG_FILE: /app/tests/test_config.json
HD_OPTIMADE_BASE_URL: https://optimade.herokuapp.com

publish_container_image:
name: Publish container image
needs: deploy_docs
uses: ./.github/workflows/cd_container_image.yml
if: needs.deploy_docs.outputs.release_run == 'false'
with:
release: false
checkout_ref: ${{ github.sha }}
secrets: inherit
permissions:
packages: write
contents: read
30 changes: 18 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
FROM python:3.7
FROM python:3.10-slim

# Prevent writing .pyc files on the import of source modules
# and set unbuffered mode to ensure logging outputs
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /app

# copy repo contents
COPY setup.py README.md ./
# Copy repo contents
COPY setup.py setup.cfg LICENSE MANIFEST.in README.md .docker/run.sh ./
COPY optimade ./optimade
COPY providers/src/links/v1/providers.json ./optimade/server/data/
RUN pip install -e .[server]

ARG PORT=5000
EXPOSE ${PORT}

COPY .docker/run.sh ./
RUN apt-get purge -y --auto-remove \
&& rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir --trusted-host pypi.org --trusted-host files.pythonhosted.org -U pip setuptools wheel flit \
&& pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org .[server]

# Setup server configuration
ARG CONFIG_FILE=optimade_config.json
COPY ${CONFIG_FILE} ./config.json
ENV OPTIMADE_CONFIG_FILE /app/config.json
COPY ${CONFIG_FILE} ./optimade_config.json
ENV OPTIMADE_CONFIG_FILE=/app/optimade_config.json

CMD ["/app/run.sh"]
# Run app
EXPOSE 5000
ENTRYPOINT [ "/app/run.sh" ]