From 1b242bb1b84ea85ee32f9361eaac05a9c8ea9369 Mon Sep 17 00:00:00 2001 From: Asim Date: Sat, 24 Feb 2024 19:52:08 +0300 Subject: [PATCH] added setup CI/CD deploy --- setup/deploy/Dockerfile | 40 ++++++++++++++++++++ setup/deploy/docker-compose.yml | 48 +++++++++++++++++++++++ setup/set-new-django-project.bash | 15 ++++++-- setup/workflows/docker-cd.yml | 36 ++++++++++++++++++ setup/workflows/docker-ci.yml | 63 +++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 setup/deploy/Dockerfile create mode 100644 setup/deploy/docker-compose.yml create mode 100644 setup/workflows/docker-cd.yml create mode 100644 setup/workflows/docker-ci.yml diff --git a/setup/deploy/Dockerfile b/setup/deploy/Dockerfile new file mode 100644 index 0000000..92f76d2 --- /dev/null +++ b/setup/deploy/Dockerfile @@ -0,0 +1,40 @@ +FROM python:3.11-slim-bullseye AS base + +FROM base AS builder + +RUN apt-get -y update && apt-get -y install gcc python3-dev libpq-dev + +COPY ./requirements.txt /requirements.txt + +RUN pip wheel --wheel-dir=/root/wheels -r /requirements.txt + +LABEL org.opencontainers.image.source=https://github.com/asim3/my_project_name +LABEL org.opencontainers.image.description="Django: my_project_name" + + + +FROM base + +RUN apt-get -y update && apt-get -y install libpq5 + +RUN adduser --system --shell /bin/bash --uid 1000 --group --disabled-password --disabled-login d_user + +ENV APP_HOME=/home/d_user/web + +RUN install -d -m 0750 -o d_user -g d_user $APP_HOME + +COPY --from=builder /root/wheels /root/wheels + +COPY --from=builder /requirements.txt $APP_HOME/requirements.txt + +RUN pip install --no-index --find-links=/root/wheels -r $APP_HOME/requirements.txt + +COPY --chown=d_user:d_user --chmod=550 ./my_project_name $APP_HOME + +WORKDIR $APP_HOME + +USER d_user + +ENTRYPOINT ["/bin/sh", "-c"] + +CMD ["gunicorn --bind :8000 --workers 3 my_project_name.wsgi"] diff --git a/setup/deploy/docker-compose.yml b/setup/deploy/docker-compose.yml new file mode 100644 index 0000000..f0e0c68 --- /dev/null +++ b/setup/deploy/docker-compose.yml @@ -0,0 +1,48 @@ +version: "3.8" +services: + app: + image: ghcr.io/asim3/my_project_name:1.2 + user: "1000:1000" + environment: + TZ: Asia/Riyadh + MY___11111111111111: "22222222222222222222222222222222" + MY___22222222222222: my Env + secrets: + - source: secret_swarmcd_key + target: /home/swarmcd/.ssh/id_ecdsa + uid: "1000" + gid: "1000" + mode: 0400 + + deploy: + mode: replicated + replicas: 2 + labels: + - traefik.enable=false + resources: + reservations: + memory: 128M + limits: + memory: 2048M + placement: + constraints: + - node.role == manager + + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + + networks: + - main-public + + ports: + - "8001:80" + + +networks: + main-public: + external: true + + +secrets: + secret_swarmcd_key: + external: true diff --git a/setup/set-new-django-project.bash b/setup/set-new-django-project.bash index c0ddaf3..e826a1d 100755 --- a/setup/set-new-django-project.bash +++ b/setup/set-new-django-project.bash @@ -28,8 +28,10 @@ update-project-name() { sed -i -e "s/my_project_name/${name}/g" ./README.md sed -i -e "s/my_project_name/${name}/g" ./setup/Dockerfile sed -i -e "s/my_project_name/${name}/g" ./setup/docker-compose.yml - sed -i -e "s/my_project_name/${name}/g" ./.github/workflows/docker-test.yml - sed -i -e "s/my_project_name/${name}/g" ./.github/workflows/docker-ci.yml + sed -i -e "s/my_project_name/${name}/g" ./setup/workflows/staging-ci.yml + sed -i -e "s/my_project_name/${name}/g" ./setup/workflows/staging-cd.yml + sed -i -e "s/my_project_name/${name}/g" ./setup/deploy/docker-compose.yml + sed -i -e "s/my_project_name/${name}/g" ./setup/deploy/Dockerfile } @@ -58,13 +60,19 @@ setup-docker() { } +setup-cicd-deploy() { + mv ./setup/workflows/staging-ci.yml ./.github/workflows/ + mv ./setup/workflows/staging-cd.yml ./.github/workflows/ + rm -rf ./.github/workflows/docker-test.yml +} + + copy-django-apps() { mv ./setup/apps/urls.py ./${name}/${name}/urls.py mv ./setup/apps/* ./${name}/ } - remove-setup-files() { rm -rf ./setup/ } @@ -76,5 +84,6 @@ setup-django-settings setup-django-static setup-dotenv setup-docker +setup-cicd-deploy copy-django-apps remove-setup-files diff --git a/setup/workflows/docker-cd.yml b/setup/workflows/docker-cd.yml new file mode 100644 index 0000000..1be9dfa --- /dev/null +++ b/setup/workflows/docker-cd.yml @@ -0,0 +1,36 @@ +name: my_project_name CD + +on: + push: + tags: + - staging-** + +env: + PROJECT_NAME: my_project_name + PROJECT_IMAGE_NAME: "ghcr.io/asim3/${{ github.event.repository.name }}" + + +jobs: + docker_deploy: + name: Deploy Docker Image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Update Stack Image Tag + run: > + GIT_REF=$(git rev-parse --verify HEAD); + ${PROJECT_IMAGE_NAME} + ${GIT_REF} + + - name: Commite the change + run: > + ls -al ./ + + - name: Make new release + run: > + ls -al ./ + + - name: Deploy Stack to SWARM + run: > + ls -al ./ diff --git a/setup/workflows/docker-ci.yml b/setup/workflows/docker-ci.yml new file mode 100644 index 0000000..7a0960c --- /dev/null +++ b/setup/workflows/docker-ci.yml @@ -0,0 +1,63 @@ +name: my_project_name CI + +on: + push: + branches: + - main + +env: + PROJECT_NAME: my_project_name + PROJECT_IMAGE_NAME: "ghcr.io/asim3/${{ github.event.repository.name }}" + + +jobs: + docker_test: + runs-on: ubuntu-latest + name: Test on Docker + steps: + - uses: actions/checkout@v4 + + - name: Copy Env File + run: cp ${PROJECT_NAME}/.env.sample ${PROJECT_NAME}/.env + + - name: Build Docker + run: > + GIT_REF=$(git rev-parse --verify HEAD); + docker image build --no-cache + -t ${PROJECT_IMAGE_NAME}:${GIT_REF} + . + + - name: Run All Django Tests + run: > + GIT_REF=$(git rev-parse --verify HEAD); + docker container run --rm + -e DJANGO_SETTINGS_MODULE=${PROJECT_NAME}.settings.docker_dev + ${PROJECT_IMAGE_NAME}:${GIT_REF} 'python3 manage.py test' + + + docker_push: + name: Push Docker Image + needs: docker_test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build Docker + run: > + GIT_REF=$(git rev-parse --verify HEAD); + docker image build --no-cache -t ${PROJECT_IMAGE_NAME}:${GIT_REF} . ; + + - name: Login To Container Registry + env: + GHCR_TOKEN: "${{ secrets.CONTAINER_REGISTRY_TOKEN }}" + run: echo ${GHCR_TOKEN} | docker login ghcr.io --username asim3 --password-stdin + + - name: Push Image To Container Registry + run: > + docker image ls -a; + GIT_REF=$(git rev-parse --verify HEAD); + docker push ${PROJECT_IMAGE_NAME}:${GIT_REF}; + + - name: Clean Up Docker Login + if: always() + run: rm -rf ~/.docker