diff --git a/.copier-docker-config.yaml b/.copier-docker-config.yaml index 95d70a8..5d1b4ec 100644 --- a/.copier-docker-config.yaml +++ b/.copier-docker-config.yaml @@ -10,10 +10,10 @@ container_workspace_root: /workspace copy_scripts_dir: true cuda_device_id: all docker_apt_packages: fontconfig fonts-nanum -docker_build_from: library/ubuntu:22.04 +docker_build_from: library/ubuntu:20.04 docker_container_uid: 9001 docker_container_username: app -docker_image_variant_name: ubuntu-22.04 +docker_image_variant_name: ubuntu-20.04 docker_image_version_variable_name: IMAGE_VERSION docker_name_prefix: DEVCON docker_project_name: devcon diff --git a/.docker/.docker-scripts/docker-compose.sh b/.docker/.docker-scripts/docker-compose.sh index 6c0463f..d253d01 100644 --- a/.docker/.docker-scripts/docker-compose.sh +++ b/.docker/.docker-scripts/docker-compose.sh @@ -22,7 +22,7 @@ $0 build -v base # declare arguments PROJECT_ID=${DOCKER_PROJECT_ID:-"default"} COMMAND="build" -VARIANT=${IMAGE_VARIANT:-"ubuntu-22.04"} +VARIANT=${IMAGE_VARIANT:-"ubuntu-20.04"} RUN_COMMAND="bash" ADDITIONAL_ARGS="" diff --git a/.docker/.ids/ubuntu-20.04.env b/.docker/.ids/ubuntu-20.04.env new file mode 100644 index 0000000..b2d0843 --- /dev/null +++ b/.docker/.ids/ubuntu-20.04.env @@ -0,0 +1,10 @@ +DOCKER_PROJECT_ID="ubuntu-20.04" + +HOST_WORKSPACE_LOCATION=${WORKSPACE_LOCATION:-"$PWD/workspace/$PROJECT_ID"} +HOST_WORKSPACE_ROOT=${WORKSPACE_ROOT:-"$HOST_WORKSPACE_LOCATION/workspace"} +HOST_SCRIPTS_DIR="$PWD/.docker/scripts" +HOST_SSH_DIR="$HOST_WORKSPACE_LOCATION/.ssh" +HOST_CACHE_DIR="$HOST_WORKSPACE_LOCATION/.cache" +HOST_HF_HOME=${HF_HOME:-"${HOST_WORKSPACE_LOCATION}/.cache/huggingface"} +HOST_GH_CONFIG_DIR="$HOST_WORKSPACE_LOCATION/.config/gh" +HOST_PASSAGE_DIR="$HOST_WORKSPACE_LOCATION/.passage" diff --git a/.docker/Dockerfile.ubuntu-20.04 b/.docker/Dockerfile.ubuntu-20.04 new file mode 100644 index 0000000..57ab3cf --- /dev/null +++ b/.docker/Dockerfile.ubuntu-20.04 @@ -0,0 +1,101 @@ +# Sets the base image for subsequent instructions +ARG ARG_BUILD_FROM="library/ubuntu:20.04" +FROM $ARG_BUILD_FROM AS builder + +# Sets labels for the image +LABEL org.opencontainers.image.source="https://github.com/entelecheia/dev-containers" +LABEL org.opencontainers.image.description="Development containers, or dev containers, are Docker containers that are specifically configured to provide a fully featured development environment." +LABEL org.opencontainers.image.licenses="MIT" + +# Setting this argument prevents interactive prompts during the build process +ARG DEBIAN_FRONTEND=noninteractive +# Updates the image and installs necessary packages +RUN apt-get update --fix-missing \ + && apt-get install -y curl wget jq sudo gosu git build-essential \ + locales locales-all fontconfig fonts-nanum \ + tzdata openssh-server \ + # Cleans up unnecessary packages to reduce image size + && apt-get autoremove -y \ + && apt-get clean -y + +# Sets Python environment variables +ENV PIP_DEFAULT_TIMEOUT 100 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + +# Setting ARGs and ENVs for the app +ARG ARG_APP_INSTALL_ROOT="/opt" +ARG ARG_APP_DIRNAME="entelecheia" +ENV APP_INSTALL_ROOT $ARG_APP_INSTALL_ROOT +ENV APP_DIRNAME $ARG_APP_DIRNAME +ENV APP_SRC_DIR=${APP_INSTALL_ROOT}/${APP_DIRNAME} +ENV APP_VIRTUAL_ENV=${APP_INSTALL_ROOT}/.venvs/${APP_DIRNAME} +ENV PATH="$APP_VIRTUAL_ENV/bin:$PATH" +ENV APP_WORKSPACE_ROOT=${APP_INSTALL_ROOT}/workspace +ARG ARG_WORKSPACE_ROOT="/workspace" +ENV WORKSPACE_ROOT $ARG_WORKSPACE_ROOT +# Sets up the workspace for the user +RUN mkdir -p $WORKSPACE_ROOT/projects + +# Sets the working directory to workspace root +WORKDIR $WORKSPACE_ROOT +# Copies scripts from host into the image +COPY ./.docker/scripts/ ./scripts/ +# RUN pip install -r ./scripts/requirements-ubuntu-20.04.txt + +# Sets the time zone within the container +ENV TZ="Asia/Seoul" +# Sets up the locale to en_US.UTF-8 +RUN localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 || true + +# Setting ARGs and ENVs for user creation and workspace setup +ARG ARG_USERNAME="app" +ARG ARG_USER_UID=9001 +ARG ARG_USER_GID=$ARG_USER_UID +ENV USERNAME $ARG_USERNAME +ENV USER_UID $ARG_USER_UID +ENV USER_GID $ARG_USER_GID + +# Creates a non-root user with sudo privileges +RUN groupadd --gid $USER_GID $USERNAME \ + && adduser --uid $USER_UID --gid $USER_GID --force-badname --disabled-password --gecos "" $USERNAME \ + && echo "$USERNAME:$USERNAME" | chpasswd \ + && adduser $USERNAME sudo \ + && echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \ + && echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Fixes sudo error related to core dumps +RUN echo "Set disable_coredump false" > /etc/sudo.conf + +# Switches to the newly created user +USER $USERNAME + +# install dotfiles +ARG ARG_USER_FULLNAME="Dev User" +ARG ARG_USER_EMAIL="dev@domain.com" +ARG ARG_GITHUB_USERNAME="" +ARG ARG_SYSTEM_HOSTNAME="dev-container" +ARG ARG_WORKSPACE_LOCATION="/" +ENV USER_FULLNAME $ARG_USER_FULLNAME +ENV USER_EMAIL $ARG_USER_EMAIL +ENV GITHUB_USERNAME $ARG_GITHUB_USERNAME +ENV SYSTEM_HOSTNAME $ARG_SYSTEM_HOSTNAME +ENV WORKSPACE_LOCATION $ARG_WORKSPACE_LOCATION + +ENV DOTFILES_APPLY_ROOTMOI=0 +ENV DOTFILES_USE_CODE=1 +ENV DOTFILES_USE_PYTHON_TOOLS=1 +ENV REMOTE_CONTAINERS=1 +# ENV DOTFILES_DEBUG=1 + +USER $USERNAME +RUN sh -c "$(wget -qO- https://dotfiles.entelecheia.ai/install)" + +USER root +RUN chown --recursive "${USER_UID}:${USER_GID}" "${WORKSPACE_ROOT}" +RUN chown --recursive "${USER_UID}:${USER_GID}" "${APP_INSTALL_ROOT}" +USER $USERNAME + +# Specifies the command that will be executed when the container is run +CMD ["bash"] diff --git a/.docker/docker-compose.ubuntu-20.04.yaml b/.docker/docker-compose.ubuntu-20.04.yaml new file mode 100644 index 0000000..f13524f --- /dev/null +++ b/.docker/docker-compose.ubuntu-20.04.yaml @@ -0,0 +1,81 @@ +version: "3" + +services: + # Defines a service name + workspace: + build: + # Sets the build context to the current directory + context: . + # Specifies the Dockerfile to use for the build + dockerfile: .docker/Dockerfile.ubuntu-20.04 + # Specifies build-time variables (ARGs) + args: + ARG_BUILD_FROM: $BUILD_FROM + ARG_USERNAME: $CONTAINER_USERNAME + ARG_USER_UID: $CONTAINER_USER_UID + ARG_USER_GID: $CONTAINER_USER_GID + ARG_WORKSPACE_ROOT: $CONTAINER_WORKSPACE_ROOT + ARG_USER_FULLNAME: $CONTAINER_USER_FULLNAME + ARG_USER_EMAIL: $CONTAINER_USER_EMAIL + ARG_GITHUB_USERNAME: $GITHUB_USERNAME + ARG_SYSTEM_HOSTNAME: $CONTAINER_HOSTNAME + ARG_WORKSPACE_LOCATION: $CONTAINER_WORKSPACE_LOCATION + ARG_DOTFILES_VERSION: $DOTFILES_VERSION + ARG_APP_INSTALL_ROOT: $APP_INSTALL_ROOT + ARG_APP_DIRNAME: $APP_DIRNAME + ARG_CONTAINER_SERVICE_NAME: $CONTAINER_SERVICE_NAME + # Sets the image name for the built image + image: $IMAGE_NAME:$IMAGE_TAG + # Sets the hostname of the container + hostname: $CONTAINER_HOSTNAME + command: + # Specifies the command to be executed when the container is run + - bash + - $CONTAINER_LAUNCH_SCRIPT + # set the environment variables + environment: + USER_UID: $CONTAINER_USER_UID + USER_GID: $CONTAINER_USER_GID + USER_FULLNAME: $CONTAINER_USER_FULLNAME + USER_EMAIL: $CONTAINER_USER_EMAIL + GITHUB_USERNAME: $CONTAINER_GITHUB_USERNAME + WORKSPACE_LOCATION: $CONTAINER_WORKSPACE_LOCATION + SYSTEM_HOSTNAME: $CONTAINER_HOSTNAME + GIT_COMMIT_GPGSIGN: $GIT_COMMIT_GPGSIGN + WORKSPACE_ROOT: $CONTAINER_WORKSPACE_ROOT + IMAGE_VARIANT: $IMAGE_VARIANT + JUPYTER_PORT: $CONTAINER_JUPYTER_PORT + JUPYTER_TOKEN: $CONTAINER_JUPYTER_TOKEN + ulimits: + # Sets the stack size and memory lock limits + stack: 67108864 + memlock: -1 + # Allows the container to use the host's IPC namespace + ipc: $CONTAINER_IPC + ports: + # Maps the container's SSH and Web service ports to the host's ports + - "$HOST_SSH_PORT:$CONTAINER_SSH_PORT" + - "$HOST_JUPYTER_PORT:$CONTAINER_JUPYTER_PORT" + - "$HOST_WEB_SVC_PORT:$CONTAINER_WEB_SVC_PORT" + volumes: + # Maps directories from the host to the container + - "$HOST_SCRIPTS_DIR:$CONTAINER_WORKSPACE_ROOT/scripts" + - "$HOST_HF_HOME:$CONTAINER_HF_HOME" + - "$HOST_WORKSPACE_ROOT:$CONTAINER_WORKSPACE_ROOT" + - "$HOST_CACHE_DIR:$CONTAINER_CACHE_DIR" + - "$HOST_SSH_DIR:$CONTAINER_SSH_DIR" + - "$HOST_GH_CONFIG_DIR:$CONTAINER_GH_CONFIG_DIR" + - "$HOST_PASSAGE_DIR:$CONTAINER_PASSAGE_DIR" + deploy: + resources: + reservations: + devices: + # Reserves the specified GPU for the container + - driver: nvidia + device_ids: ["${CONTAINER_CUDA_DEVICE_ID}"] + capabilities: [gpu] +networks: + default: + # Sets the name of the default network and makes it external + name: $CONTAINER_NETWORK_NAME + external: true diff --git a/.docker/docker.ubuntu-20.04.env b/.docker/docker.ubuntu-20.04.env new file mode 100644 index 0000000..65f804e --- /dev/null +++ b/.docker/docker.ubuntu-20.04.env @@ -0,0 +1,29 @@ +######################################################### +# Configuration parameters for the docker project # +# Change the variables below to your need: # +######################################################### +CONTAINER_GITHUB_USERNAME=${GITHUB_USERNAME:-"entelecheia"} # The GitHub username of the project +CONTAINER_USER_FULLNAME=${USER_FULLNAME:-"Young Joon Lee"} # The full name of the user +CONTAINER_USER_EMAIL=${USER_EMAIL:-"entelecheia@hotmail.com"} # The email address of the user + +####################################################################################### +# Please do not make any changes below this line if you don't know what you are doing # +# change the variables above to your need # +####################################################################################### +# docker build: Configuration parameters for building the Docker image +IMAGE_VARIANT=${IMAGE_VARIANT:-"ubuntu-20.04"} # The variant of the Docker image. +IMAGE_TAG="${IMAGE_VERSION}-${IMAGE_VARIANT}" # The tag of the Docker image +IMAGE_NAME="${CONTAINER_REGISTRY}/${DOCKER_USERNAME}/${DOCKER_PROJECT_NAME}" # The full name of the Docker image +BUILD_FROM="library/ubuntu:20.04" # The base image for the Docker build + +# docker run: Configuration parameters for running the Docker container +CONTAINER_LAUNCH_SCRIPT="${CONTAINER_WORKSPACE_ROOT}/scripts/launch.sh" # The name of the launch script +CONTAINER_CUDA_DEVICE_ID=${DEVCON_CUDA_DEVICE_ID:-"all"} # The ID of the CUDA device to use, e.g. all, 0, 1, 2, etc. +CONTAINER_SSH_PORT=${SSH_PORT:-"22"} # The SSH port in the Docker container +HOST_SSH_PORT=${DEVCON_HOST_SSH_PORT:-"2929"} # The SSH port on the host machine to be mapped to the container's SSH port +CONTAINER_JUPYTER_PORT=${JUPYTER_PORT:-"8585"} # The Jupyter port in the Docker container +HOST_JUPYTER_PORT=${DEVCON_HOST_JUPYTER_PORT:-"18998"} # The Jupyter port on the host machine to be mapped to the container's Jupyter port +CONTAINER_JUPYTER_TOKEN=${DEVCON_JUPYTER_TOKEN:-"__juypter_token_(change_me)__"} # The Jupyter token to use +CONTAINER_SERVICE_NAME=${DEVCON_SERVICE_NAME:-"app"} # The server name (optional, can be left empty) +CONTAINER_WEB_SVC_PORT=${WEB_SVC_PORT:-"8080"} # The Web service port in the Docker container +HOST_WEB_SVC_PORT=${DEVCON_HOST_WEB_SVC_PORT-"19090"} # The Web service port on the host machine to be mapped to the container's Web service port diff --git a/.github/workflows/deploy-ubuntu-20.04-image.yaml b/.github/workflows/deploy-ubuntu-20.04-image.yaml new file mode 100644 index 0000000..47dc178 --- /dev/null +++ b/.github/workflows/deploy-ubuntu-20.04-image.yaml @@ -0,0 +1,86 @@ +# +name: deploy-ubuntu-20.04-image + +# Configures this workflow to run every time a change is pushed to the branch called `release`. +on: + workflow_call: + workflow_dispatch: + push: + branches: + - docker* + paths: + - ".docker/**" + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Secure disk space for the build + run: bash .github/scripts/free-disk-space.sh + + - name: Version from version file + uses: c-py/action-dotenv-to-setenv@v5 + with: + env-file: ./.docker/docker.version + + - name: Common environment Variables from Dotenv + uses: c-py/action-dotenv-to-setenv@v5 + with: + # use branch name as suffix for dotfile + env-file: ./.docker/docker.common.env + + - name: Environment Variables from Dotenv + uses: c-py/action-dotenv-to-setenv@v5 + with: + # use branch name as suffix for dotfile + env-file: ./.docker/docker.ubuntu-20.04.env + + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@v3.1.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5.5.1 + with: + images: ${{ env.IMAGE_NAME }} + tags: | + type=raw,value=${{ env.IMAGE_VERSION }}-${{ env.IMAGE_VARIANT }} + # set latest tag for docker branch + type=raw,value=latest-${{ env.IMAGE_VARIANT }} + + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image + uses: docker/build-push-action@v5.3.0 + with: + context: . + file: ./.docker/Dockerfile.base + build-args: | + ARG_BUILD_FROM=${{ env.BUILD_FROM }} + ARG_USERNAME=${{ env.CONTAINER_USERNAME }} + ARG_USER_UID=${{ env.CONTAINER_USER_UID }} + ARG_USER_GID=${{ env.CONTAINER_USER_GID }} + ARG_WORKSPACE_ROOT=${{ env.CONTAINER_WORKSPACE_ROOT }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Makefile b/Makefile index c943aef..c3439a5 100644 --- a/Makefile +++ b/Makefile @@ -96,31 +96,31 @@ docker-login: ## login to docker @bash .docker/.docker-scripts/docker-compose.sh login docker-build: ## build the docker app image - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh build docker-config: ## show the docker app config - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh config docker-push: ## push the docker app image - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh push docker-run: ## run the docker base image - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh run docker-up: ## launch the docker app image - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh up docker-up-detach: ## launch the docker app image in detached mode - @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-22.04"} \ + @IMAGE_VARIANT=$${IMAGE_VARIANT:-"ubuntu-20.04"} \ DOCKER_PROJECT_ID=$${DOCKER_PROJECT_ID:-"default"} \ bash .docker/.docker-scripts/docker-compose.sh up --detach