You've already forked hotpocket
BTHLABS-63: Production deployment workflow
This commit is contained in:
19
.gitea/actions/setup-ansible/action.yaml
Normal file
19
.gitea/actions/setup-ansible/action.yaml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: "Set up Ansible"
|
||||||
|
description: "Downloads and installs Ansible"
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Ansible version to install"
|
||||||
|
required: false
|
||||||
|
default: "10.2.0"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: "Install Ansible"
|
||||||
|
shell: "bash"
|
||||||
|
env:
|
||||||
|
PIP_INDEX_URL: "https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
python3 -m venv /opt/ansible
|
||||||
|
|
||||||
|
/opt/ansible/bin/pip install ansible==${{ inputs.version }}
|
||||||
81
.gitea/workflows/build-deployment-images.yaml
Normal file
81
.gitea/workflows/build-deployment-images.yaml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: "Build deployment images"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
required: true
|
||||||
|
type: "string"
|
||||||
|
registry:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
default: "docker-hosted.nexus.bthlabs.pl"
|
||||||
|
platform:
|
||||||
|
required: false
|
||||||
|
type: "string"
|
||||||
|
default: "linux/amd64,linux/arm64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID:
|
||||||
|
required: true
|
||||||
|
VAULT_SECRET_ID:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-deployment-images:
|
||||||
|
name: "Build deployment images"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout the code"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
|
- name: "Get `backend` version"
|
||||||
|
id: "get-backend-version"
|
||||||
|
uses: "./.gitea/actions/get-service-version"
|
||||||
|
with:
|
||||||
|
service: "backend"
|
||||||
|
- name: "Import Secrets"
|
||||||
|
id: "import-secrets"
|
||||||
|
uses: "hashicorp/vault-action@v2"
|
||||||
|
with:
|
||||||
|
url: "https://vault.bthlabs.pl/"
|
||||||
|
method: "approle"
|
||||||
|
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
secrets: |
|
||||||
|
gitea/data/${{ inputs.registry }} username | DOCKER_USERNAME ;
|
||||||
|
gitea/data/${{ inputs.registry }} password | DOCKER_PASSWORD
|
||||||
|
- name: "Set up Docker Buildx"
|
||||||
|
id: "setup-docker-buildx"
|
||||||
|
uses: "docker/setup-buildx-action@v3"
|
||||||
|
with:
|
||||||
|
driver: "remote"
|
||||||
|
endpoint: "tcp://builder-01.bthlab:2375"
|
||||||
|
platforms: "linux/amd64"
|
||||||
|
append: |
|
||||||
|
- endpoint: "tcp://builder-mac-01.bthlab:2375"
|
||||||
|
platforms: "linux/arm64"
|
||||||
|
- name: "Login to Docker Registry"
|
||||||
|
uses: "docker/login-action@v3"
|
||||||
|
with:
|
||||||
|
registry: "${{ inputs.registry }}"
|
||||||
|
username: "${{ steps.import-secrets.outputs.DOCKER_USERNAME }}"
|
||||||
|
password: "${{ steps.import-secrets.outputs.DOCKER_PASSWORD }}"
|
||||||
|
- name: "Build `backend-aio` image"
|
||||||
|
env:
|
||||||
|
SHORT_SHA: "${{ steps.get-build-options.outputs.short-sha }}"
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
docker buildx build \
|
||||||
|
--cache-from "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket" \
|
||||||
|
--cache-to "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,target=max" \
|
||||||
|
--push \
|
||||||
|
--platform "${{ inputs.platform }}" \
|
||||||
|
--build-arg IMAGE_ID="${{ inputs.target }}.${SHORT_SHA}" \
|
||||||
|
-f services/backend/Dockerfile \
|
||||||
|
--target "${{ inputs.target }}" \
|
||||||
|
-t "${{ inputs.registry }}/hotpocket/backend:${{ inputs.target }}-${VERSION}-${BUILD}" \
|
||||||
|
services/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: "Deploy to development"
|
name: "Development deployment"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,81 +6,28 @@ on:
|
|||||||
- "development"
|
- "development"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-deployment-images:
|
build-for-development:
|
||||||
name: "Build deployment images"
|
name: "Build"
|
||||||
runs-on: "ubuntu-latest"
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
steps:
|
|
||||||
- name: "Checkout the code"
|
|
||||||
uses: "actions/checkout@v2"
|
|
||||||
- name: "Get build options"
|
|
||||||
id: "get-build-options"
|
|
||||||
uses: "./.gitea/actions/get-build-options"
|
|
||||||
- name: "Get `backend` version"
|
|
||||||
id: "get-backend-version"
|
|
||||||
uses: "./.gitea/actions/get-service-version"
|
|
||||||
with:
|
|
||||||
service: "backend"
|
|
||||||
- name: "Import Secrets"
|
|
||||||
id: "import-secrets"
|
|
||||||
uses: "hashicorp/vault-action@v2"
|
|
||||||
with:
|
|
||||||
url: "https://vault.bthlabs.pl/"
|
|
||||||
method: "approle"
|
|
||||||
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
|
||||||
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
|
||||||
secrets: |
|
|
||||||
gitea/data/docker-hosted.nexus.bthlab.bthlabs.net username | DOCKER_USERNAME ;
|
|
||||||
gitea/data/docker-hosted.nexus.bthlab.bthlabs.net password | DOCKER_PASSWORD
|
|
||||||
- name: "Set up Docker Buildx"
|
|
||||||
id: "setup-docker-buildx"
|
|
||||||
uses: "docker/setup-buildx-action@v3"
|
|
||||||
with:
|
|
||||||
driver: "remote"
|
|
||||||
endpoint: "tcp://builder-01.bthlab:2375"
|
|
||||||
platforms: "linux/amd64"
|
|
||||||
append: |
|
|
||||||
- endpoint: "tcp://builder-mac-01.bthlab:2375"
|
|
||||||
platforms: "linux/arm64"
|
|
||||||
- name: "Login to Docket Registry"
|
|
||||||
uses: "docker/login-action@v3"
|
|
||||||
with:
|
with:
|
||||||
|
target: "deployment"
|
||||||
|
platform: "linux/amd64"
|
||||||
registry: "nexus.bthlab.bthlabs.net:8002"
|
registry: "nexus.bthlab.bthlabs.net:8002"
|
||||||
username: "${{ steps.import-secrets.outputs.DOCKER_USERNAME }}"
|
secrets:
|
||||||
password: "${{ steps.import-secrets.outputs.DOCKER_PASSWORD }}"
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
- name: "Build `backend-deployment` image"
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
env:
|
|
||||||
SHORT_SHA: "${{ steps.get-build-options.outputs.short-sha }}"
|
|
||||||
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
|
||||||
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
docker buildx build \
|
|
||||||
--cache-from "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket" \
|
|
||||||
--cache-to "type=registry,ref=nexus.bthlab.bthlabs.net:8001/hotpocket,mode=max" \
|
|
||||||
--push \
|
|
||||||
--platform linux/amd64 \
|
|
||||||
--build-arg IMAGE_ID="deployment.${SHORT_SHA}" \
|
|
||||||
-f services/backend/Dockerfile \
|
|
||||||
--target deployment \
|
|
||||||
-t "nexus.bthlab.bthlabs.net:8002/hotpocket/backend:deployment-${VERSION}-${BUILD}" \
|
|
||||||
services/
|
|
||||||
|
|
||||||
deploy:
|
deploy-to-deployment:
|
||||||
name: "Deploy"
|
name: "Deploy"
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
needs:
|
needs:
|
||||||
- "build-deployment-images"
|
- "build-for-development"
|
||||||
env:
|
env:
|
||||||
KUBERNETES_NAMESPACE: "hotpocket-development"
|
KUBERNETES_NAMESPACE: "hotpocket-development"
|
||||||
KUBERNETES_CLUSTER: "k8s.bthlab"
|
KUBERNETES_CLUSTER: "k8s.bthlab"
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout the code"
|
- name: "Checkout the code"
|
||||||
uses: "actions/checkout@v2"
|
uses: "actions/checkout@v2"
|
||||||
- name: "Get run info"
|
|
||||||
id: "get-run-info"
|
|
||||||
uses: "./.gitea/actions/get-run-info"
|
|
||||||
with:
|
|
||||||
compose-project-base: "${{ vars.COMPOSE_PROJECT_BASE }}"
|
|
||||||
- name: "Get build options"
|
- name: "Get build options"
|
||||||
id: "get-build-options"
|
id: "get-build-options"
|
||||||
uses: "./.gitea/actions/get-build-options"
|
uses: "./.gitea/actions/get-build-options"
|
||||||
@@ -105,7 +52,6 @@ jobs:
|
|||||||
gitea/data/k8s.bthlab config | KUBECONFIG_PAYLOAD
|
gitea/data/k8s.bthlab config | KUBECONFIG_PAYLOAD
|
||||||
- name: "Set up kubeconfig"
|
- name: "Set up kubeconfig"
|
||||||
env:
|
env:
|
||||||
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
|
||||||
KUBECONFIG_PAYLOAD: "${{ steps.import-secrets.outputs.KUBECONFIG_PAYLOAD }}"
|
KUBECONFIG_PAYLOAD: "${{ steps.import-secrets.outputs.KUBECONFIG_PAYLOAD }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@@ -117,7 +63,6 @@ jobs:
|
|||||||
/opt/k8s/bin/kubectl get node
|
/opt/k8s/bin/kubectl get node
|
||||||
- name: "Run `backend` Django migrations"
|
- name: "Run `backend` Django migrations"
|
||||||
env:
|
env:
|
||||||
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
|
||||||
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@@ -126,6 +71,7 @@ jobs:
|
|||||||
cd deployment/hotpocket.bthlab ;
|
cd deployment/hotpocket.bthlab ;
|
||||||
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
export KUBECONFIG="/opt/k8s/etc/kubeconfig" ;
|
||||||
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
/opt/k8s/bin/kubectl config use-context ${KUBERNETES_CLUSTER} ;
|
||||||
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} apply -f resources/backend/config-map-local-deps.yaml ;
|
||||||
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} set image cronjobs/backend-job-migrations migrations=nexus.bthlab.bthlabs.net:8002/hotpocket/backend:${BACKEND_TAG} ;
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} set image cronjobs/backend-job-migrations migrations=nexus.bthlab.bthlabs.net:8002/hotpocket/backend:${BACKEND_TAG} ;
|
||||||
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} delete jobs --ignore-not-found=true backend-job-migrations ;
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} delete jobs --ignore-not-found=true backend-job-migrations ;
|
||||||
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} create job backend-job-migrations --from=cronjob/backend-job-migrations ;
|
/opt/k8s/bin/kubectl -n ${KUBERNETES_NAMESPACE} create job backend-job-migrations --from=cronjob/backend-job-migrations ;
|
||||||
@@ -133,7 +79,6 @@ jobs:
|
|||||||
)
|
)
|
||||||
- name: "Deploy"
|
- name: "Deploy"
|
||||||
env:
|
env:
|
||||||
COMPOSE_PROJECT: "${{ steps.get-run-info.outputs.compose-project }}"
|
|
||||||
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
BACKEND_TAG: "deployment-${{ steps.get-backend-version.outputs.version }}-${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
|
|||||||
76
.gitea/workflows/production.yaml
Normal file
76
.gitea/workflows/production.yaml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
name: "Production deployment"
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: ["published"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-for-production:
|
||||||
|
name: "Build"
|
||||||
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
|
with:
|
||||||
|
target: "deployment"
|
||||||
|
platform: "linux/amd64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
|
||||||
|
deploy-to-production:
|
||||||
|
name: "Deploy"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
needs:
|
||||||
|
- "build-for-production"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout the code"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
|
- name: "Get `backend` version"
|
||||||
|
id: "get-backend-version"
|
||||||
|
uses: "./.gitea/actions/get-service-version"
|
||||||
|
with:
|
||||||
|
service: "backend"
|
||||||
|
- name: "Import Secrets"
|
||||||
|
id: "import-secrets"
|
||||||
|
uses: "hashicorp/vault-action@v2"
|
||||||
|
with:
|
||||||
|
url: "https://vault.bthlabs.pl/"
|
||||||
|
method: "approle"
|
||||||
|
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
secrets: |
|
||||||
|
gitea/data/hotpocket.app ansible_vault_payload | ANSIBLE_VAULT_PAYLOAD ;
|
||||||
|
gitea/data/hotpocket.app ansible_vault_password | ANSIBLE_VAULT_PASSWORD ;
|
||||||
|
gitea/data/hotpocket.app ansible_inventory_payload | ANSIBLE_INVENTORY_PAYLOAD ;
|
||||||
|
gitea/data/hotpocket.app ssh_key_payload | SSH_KEY_PAYLOAD
|
||||||
|
- name: "Setup Ansible"
|
||||||
|
uses: "./.gitea/actions/setup-ansible"
|
||||||
|
- name: "Prepare Ansible secrets"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir deployment/hotpocket_app/.ci
|
||||||
|
echo "${ANSIBLE_VAULT_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/env_vars/production/vault.yaml"
|
||||||
|
echo "${ANSIBLE_VAULT_PASSWORD}" >"deployment/hotpocket_app/.ci/vault_password"
|
||||||
|
echo "${ANSIBLE_INVENTORY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/inventory_ci.yaml"
|
||||||
|
echo "${SSH_KEY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/.ci/ssh_key"
|
||||||
|
chmod 600 deployment/hotpocket_app/.ci/ssh_key
|
||||||
|
- name: "Engage!"
|
||||||
|
env:
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket_app ;
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING="False" /opt/ansible/bin/ansible-playbook \
|
||||||
|
-i inventory_ci.yaml \
|
||||||
|
--vault-id hotpocket@.ci/vault_password \
|
||||||
|
-e @env_vars/production/vars.yaml \
|
||||||
|
-e @env_vars/production/vault.yaml \
|
||||||
|
-e hotpocket_app_image_tag="deployment-${VERSION}-${BUILD}" \
|
||||||
|
--limit "*.production.hotpocket.app" \
|
||||||
|
deploy.yaml
|
||||||
|
)
|
||||||
76
.gitea/workflows/staging.yaml
Normal file
76
.gitea/workflows/staging.yaml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
name: "Staging deployment"
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: ["published"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-for-staging:
|
||||||
|
name: "Build"
|
||||||
|
uses: "./.gitea/workflows/build-deployment-images.yaml"
|
||||||
|
with:
|
||||||
|
target: "aio"
|
||||||
|
platform: "linux/amd64"
|
||||||
|
secrets:
|
||||||
|
VAULT_ROLE_ID: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
VAULT_SECRET_ID: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
|
||||||
|
deploy-to-staging:
|
||||||
|
name: "Deploy"
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
needs:
|
||||||
|
- "build-for-staging"
|
||||||
|
steps:
|
||||||
|
- name: "Checkout the code"
|
||||||
|
uses: "actions/checkout@v2"
|
||||||
|
- name: "Get build options"
|
||||||
|
id: "get-build-options"
|
||||||
|
uses: "./.gitea/actions/get-build-options"
|
||||||
|
- name: "Get `backend` version"
|
||||||
|
id: "get-backend-version"
|
||||||
|
uses: "./.gitea/actions/get-service-version"
|
||||||
|
with:
|
||||||
|
service: "backend"
|
||||||
|
- name: "Import Secrets"
|
||||||
|
id: "import-secrets"
|
||||||
|
uses: "hashicorp/vault-action@v2"
|
||||||
|
with:
|
||||||
|
url: "https://vault.bthlabs.pl/"
|
||||||
|
method: "approle"
|
||||||
|
roleId: "${{ secrets.VAULT_ROLE_ID }}"
|
||||||
|
secretId: "${{ secrets.VAULT_SECRET_ID }}"
|
||||||
|
secrets: |
|
||||||
|
gitea/data/staging.hotpocket.app ansible_vault_payload | ANSIBLE_VAULT_PAYLOAD ;
|
||||||
|
gitea/data/staging.hotpocket.app ansible_vault_password | ANSIBLE_VAULT_PASSWORD ;
|
||||||
|
gitea/data/staging.hotpocket.app ansible_inventory_payload | ANSIBLE_INVENTORY_PAYLOAD ;
|
||||||
|
gitea/data/staging.hotpocket.app ssh_key_payload | SSH_KEY_PAYLOAD
|
||||||
|
- name: "Setup Ansible"
|
||||||
|
uses: "./.gitea/actions/setup-ansible"
|
||||||
|
- name: "Prepare Ansible secrets"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir deployment/hotpocket_app/.ci
|
||||||
|
echo "${ANSIBLE_VAULT_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/env_vars/staging/vault.yaml"
|
||||||
|
echo "${ANSIBLE_VAULT_PASSWORD}" >"deployment/hotpocket_app/.ci/vault_password"
|
||||||
|
echo "${ANSIBLE_INVENTORY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/inventory_ci.yaml"
|
||||||
|
echo "${SSH_KEY_PAYLOAD}" | base64 -d >"deployment/hotpocket_app/.ci/ssh_key"
|
||||||
|
chmod 600 deployment/hotpocket_app/.ci/ssh_key
|
||||||
|
- name: "Engage!"
|
||||||
|
env:
|
||||||
|
VERSION: "${{ steps.get-backend-version.outputs.version }}"
|
||||||
|
BUILD: "${{ steps.get-backend-version.outputs.build-number }}"
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
|
||||||
|
(
|
||||||
|
cd deployment/hotpocket_app ;
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING="False" /opt/ansible/bin/ansible-playbook \
|
||||||
|
-i inventory_ci.yaml \
|
||||||
|
--vault-id hotpocket@.ci/vault_password \
|
||||||
|
-e @env_vars/staging/vars.yaml \
|
||||||
|
-e @env_vars/staging/vault.yaml \
|
||||||
|
-e hotpocket_app_image_tag="aio-${VERSION}-${BUILD}" \
|
||||||
|
--limit "*.staging.hotpocket.app" \
|
||||||
|
deploy.yaml
|
||||||
|
)
|
||||||
@@ -15,4 +15,4 @@ data:
|
|||||||
./manage.py collectstatic --no-input
|
./manage.py collectstatic --no-input
|
||||||
)
|
)
|
||||||
requirements.txt: |
|
requirements.txt: |
|
||||||
hotpocket_bthlabs==25.10.27
|
hotpocket_bthlabs>=25.10.28
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ spec:
|
|||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: backend-vault
|
name: backend-vault
|
||||||
key: secret_id
|
key: secret_id
|
||||||
|
- name: HOTPOCKET_BACKEND_CREATE_INITIAL_ACCOUNT
|
||||||
|
value: "true"
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
3
deployment/hotpocket_app/.gitignore
vendored
Normal file
3
deployment/hotpocket_app/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.ci/
|
||||||
|
inventory_ci.yaml
|
||||||
|
vault.yaml
|
||||||
5
deployment/hotpocket_app/deploy.yaml
Normal file
5
deployment/hotpocket_app/deploy.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
- name: "Deploy HotPocket"
|
||||||
|
hosts: "hotpocket_app"
|
||||||
|
roles:
|
||||||
|
- role: "hotpocket_app"
|
||||||
|
tags: ["hotpocket-app"]
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export PIP_INDEX_URL="https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
/srv/venv/bin/pip install -r /srv/lib/backend/requirements.txt
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
(
|
||||||
|
cd /srv/app;
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hotpocket-bthlabs>=25.10.28
|
||||||
60
deployment/hotpocket_app/env_vars/production/vars.yaml
Normal file
60
deployment/hotpocket_app/env_vars/production/vars.yaml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
deployment_directory: "/srv/hotpocket"
|
||||||
|
owner: "hotpocket"
|
||||||
|
group: "hotpocket"
|
||||||
|
mode: "fullstack"
|
||||||
|
loki:
|
||||||
|
url: "http://monitoring.vm.snakeweb.net.bthlabs.net:3100/loki/api/v1/push"
|
||||||
|
node: "home.vm.snakeweb.net"
|
||||||
|
docker:
|
||||||
|
extra_hosts:
|
||||||
|
- "home.vm:10.0.1.2"
|
||||||
|
backend:
|
||||||
|
image_tag: "{{ hotpocket_app_image_tag|default('deployment-v25.10.21-01') }}"
|
||||||
|
database:
|
||||||
|
name: "thisissecret"
|
||||||
|
user: "thisissecret"
|
||||||
|
host: "thisissecret"
|
||||||
|
rabbitmq:
|
||||||
|
vhost: "thisissecret"
|
||||||
|
user: "thisissecret"
|
||||||
|
host: "thisissecret"
|
||||||
|
model_auth_is_disabled: true
|
||||||
|
env: "production"
|
||||||
|
extra_env:
|
||||||
|
- "HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets"
|
||||||
|
- "VAULT_URL={{ hotpocket_app_secrets.backend.vault.url }}"
|
||||||
|
- "VAULT_ROLE_ID={{ hotpocket_app_secrets.backend.vault.role_id }}"
|
||||||
|
- "VAULT_SECRET_ID={{ hotpocket_app_secrets.backend.vault.secret_id }}"
|
||||||
|
oidc:
|
||||||
|
enabled: true
|
||||||
|
endpoint: "thisissecret"
|
||||||
|
display_name: "thisissecret"
|
||||||
|
webapp:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.webapp"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-webapp,environment=production"
|
||||||
|
allowed_hosts:
|
||||||
|
- "my.hotpocket.app"
|
||||||
|
admin:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.admin"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-admin,environment=production"
|
||||||
|
allowed_hosts:
|
||||||
|
- "admin.hotpocket.app"
|
||||||
|
celery_worker:
|
||||||
|
concurrency: 2
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-celery-worker,environment=production"
|
||||||
|
celery_beat:
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-celery-beat,environment=production"
|
||||||
|
customization:
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/production/lib/backend/requirements.txt"
|
||||||
|
dest: "lib/backend/requirements.txt"
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
export PIP_INDEX_URL="https://nexus.bthlabs.pl/repository/pypi/simple/"
|
||||||
|
/srv/venv/bin/pip install -r /srv/lib/backend/requirements.txt
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
(
|
||||||
|
cd /srv/app;
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hotpocket-bthlabs>=25.10.28
|
||||||
37
deployment/hotpocket_app/env_vars/staging/vars.yaml
Normal file
37
deployment/hotpocket_app/env_vars/staging/vars.yaml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
deployment_directory: "/srv/hotpocket_staging"
|
||||||
|
owner: "hotpocket_staging"
|
||||||
|
group: "hotpocket_staging"
|
||||||
|
mode: "aio"
|
||||||
|
loki:
|
||||||
|
url: "http://monitoring.vm.snakeweb.net.bthlabs.net:3100/loki/api/v1/push"
|
||||||
|
node: "home.vm.snakeweb.net"
|
||||||
|
docker:
|
||||||
|
extra_hosts:
|
||||||
|
- "home.vm:10.0.1.2"
|
||||||
|
backend:
|
||||||
|
image_tag: "{{ hotpocket_app_image_tag|default('aio-v25.10.29-rc1-01') }}"
|
||||||
|
model_auth_is_disabled: false
|
||||||
|
env: "staging"
|
||||||
|
extra_env:
|
||||||
|
- "HOTPOCKET_BACKEND_SECRETS_PACKAGE=hotpocket_bthlabs.secrets"
|
||||||
|
- "VAULT_URL={{ hotpocket_app_secrets.backend.vault.url }}"
|
||||||
|
- "VAULT_ROLE_ID={{ hotpocket_app_secrets.backend.vault.role_id }}"
|
||||||
|
- "VAULT_SECRET_ID={{ hotpocket_app_secrets.backend.vault.secret_id }}"
|
||||||
|
oidc:
|
||||||
|
enabled: false
|
||||||
|
webapp:
|
||||||
|
settings_module: "hotpocket_bthlabs.settings.webapp"
|
||||||
|
loki:
|
||||||
|
external_labels: "job=hotpocket,service=backend-webapp,environment=staging"
|
||||||
|
allowed_hosts:
|
||||||
|
- "staging.hotpocket.app"
|
||||||
|
customization:
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/01-install-customized-deps.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
dest: "etc/backend/entrypoint.d/99-collectstatic.sh"
|
||||||
|
mode: "755"
|
||||||
|
- src: "{{ inventory_dir }}/env_vars/staging/lib/backend/requirements.txt"
|
||||||
|
dest: "lib/backend/requirements.txt"
|
||||||
10
deployment/hotpocket_app/inventory.yaml
Normal file
10
deployment/hotpocket_app/inventory.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
hotpocket_app:
|
||||||
|
hosts:
|
||||||
|
web1.staging.hotpocket.app:
|
||||||
|
ansible_host: vm-125.homelab01.bthlab
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_user: hotpocket_staging
|
||||||
|
web1.production.hotpocket.app:
|
||||||
|
ansible_host: vm-125.homelab01.bthlab
|
||||||
|
ansible_port: 22
|
||||||
|
ansible_user: hotpocket
|
||||||
73
deployment/hotpocket_app/roles/hotpocket_app/tasks/main.yaml
Normal file
73
deployment/hotpocket_app/roles/hotpocket_app/tasks/main.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
- name: "Create workspace directories"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ hotpocket_app.deployment_directory }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
loop:
|
||||||
|
- "etc"
|
||||||
|
- "etc/backend"
|
||||||
|
- "etc/backend/entrypoint.d"
|
||||||
|
- "lib"
|
||||||
|
- "lib/backend"
|
||||||
|
- "log"
|
||||||
|
- "run"
|
||||||
|
- "run/backend-admin"
|
||||||
|
- "run/backend-celery-beat"
|
||||||
|
- "run/backend-celery-worker"
|
||||||
|
- "run/backend-webapp"
|
||||||
|
- "run/uploads"
|
||||||
|
- name: "Install docker-compose.yml"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app.mode }}/docker-compose.yaml.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/docker-compose.yaml"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
- name: "Install env files"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app.mode }}/{{ item }}.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/etc/{{ item }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
loop: "{{ hotpocket_app_role.env_files[hotpocket_app.mode] }}"
|
||||||
|
- name: "Upload customization files"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/{{ item.dest }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
mode: "{{ item.mode|default('644') }}"
|
||||||
|
loop: "{{ hotpocket_app.customization }}"
|
||||||
|
when: "hotpocket_app.customization is defined"
|
||||||
|
- name: "Install hotpocket_app.service unit"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ hotpocket_app_role.services[hotpocket_app.mode].src }}.jinja2"
|
||||||
|
dest: "{{ hotpocket_app.deployment_directory }}/etc/{{ hotpocket_app_role.services[hotpocket_app.mode].dest }}"
|
||||||
|
owner: "{{ hotpocket_app.owner }}"
|
||||||
|
group: "{{ hotpocket_app.group }}"
|
||||||
|
- name: "Stop the stack"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "down"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
- name: "Run backend migrations"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "run"
|
||||||
|
- "--rm"
|
||||||
|
- "backend-webapp"
|
||||||
|
- "./manage.py"
|
||||||
|
- "migrate"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
when: "hotpocket_app.mode == 'fullstack' and is_manual_run is not defined"
|
||||||
|
- name: "Start the stack"
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "compose"
|
||||||
|
- "up"
|
||||||
|
- "-d"
|
||||||
|
chdir: "{{ hotpocket_app.deployment_directory }}"
|
||||||
|
when: "is_manual_run is not defined"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.webapp.settings_module|default('hotpocket_backend.settings.aio')}}"
|
||||||
|
HOTPOCKET_BACKEND_ENV="{{ hotpocket_app.backend.env|default('aio') }}"
|
||||||
|
HOTPOCKET_BACKEND_MODEL_AUTH_IS_DISABLED="{% if hotpocket_app.backend.model_auth_is_disabled %}true{% else %}false{% endif %}"
|
||||||
|
|
||||||
|
{% if hotpocket_app.backend.oidc.enabled %}HOTPOCKET_BACKEND_OIDC_PAYLOAD='{"endpoint":"{{ hotpocket_app.backend.oidc.endpoint }}","key":"{{ hotpocket_app_secrets.backend.oidc.key }}","secret":"{{ hotpocket_app_secrets.backend.oidc.secret }}","display_name":"{{ hotpocket_app.backend.oidc.display_name }}"}'{% else %}#noop{% endif %}
|
||||||
|
|
||||||
|
{% for extra_env in hotpocket_app.backend.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
HOTPOCKET_BACKEND_SECRET_KEY: "{{ hotpocket_app_secrets.backend.webapp.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.webapp.allowed_hosts|join(',') }}"
|
||||||
|
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "{{ hotpocket_app_secrets.backend.webapp.initial_account.username }}"
|
||||||
|
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD: "{{ hotpocket_app_secrets.backend.webapp.initial_account.password }}"
|
||||||
|
{% for extra_env in hotpocket_app.backend.webapp.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
services:
|
||||||
|
backend-webapp:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.webapp.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts|default([]) %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-webapp:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.admin.settings_module|default('hotpocket_backend.settings.deployment.admin')}}"
|
||||||
|
HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
|
HOTPOCKET_BACKEND_APP="admin"
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY="{{ hotpocket_app_secrets.backend.admin.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.admin.allowed_hosts|join(',') }}"
|
||||||
|
{% for extra_env in hotpocket_app.backend.admin.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
HOTPOCKET_BACKEND_ENV="{{ hotpocket_app.backend.env|default('deployment') }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_NAME="{{ hotpocket_app.backend.database.name }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_USER="{{ hotpocket_app.backend.database.user }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_PASSWORD="{{ hotpocket_app_secrets.backend.database.password }}"
|
||||||
|
HOTPOCKET_BACKEND_DATABASE_HOST="{{ hotpocket_app.backend.database.host }}"
|
||||||
|
HOTPOCKET_BACKEND_CELERY_BROKER_URL="amqp://{{ hotpocket_app.backend.rabbitmq.user }}:{{ hotpocket_app_secrets.backend.rabbitmq.password }}@{{ hotpocket_app.backend.rabbitmq.host }}/{{ hotpocket_app.backend.rabbitmq.vhost }}"
|
||||||
|
HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND="db+postgresql+psycopg://{{ hotpocket_app.backend.database.user }}:{{ hotpocket_app_secrets.backend.database.password }}@{{ hotpocket_app.backend.database.host }}/{{ hotpocket_app.backend.database.name }}"
|
||||||
|
HOTPOCKET_BACKEND_MODEL_AUTH_IS_DISABLED="{% if hotpocket_app.backend.model_auth_is_disabled %}true{% else %}false{% endif %}"
|
||||||
|
|
||||||
|
{% if hotpocket_app.backend.oidc.enabled %}HOTPOCKET_BACKEND_OIDC_PAYLOAD='{"endpoint":"{{ hotpocket_app.backend.oidc.endpoint }}","key":"{{ hotpocket_app_secrets.backend.oidc.key }}","secret":"{{ hotpocket_app_secrets.backend.oidc.secret }}","display_name":"{{ hotpocket_app.backend.oidc.display_name }}"}'{% else %}#noop{% endif %}
|
||||||
|
|
||||||
|
{% for extra_env in hotpocket_app.backend.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
DJANGO_SETTINGS_MODULE="{{ hotpocket_app.backend.webapp.settings_module|default('hotpocket_backend.settings.deployment.webapp')}}"
|
||||||
|
HOTPOCKET_BACKEND_APP="webapp"
|
||||||
|
HOTPOCKET_BACKEND_SECRET_KEY="{{ hotpocket_app_secrets.backend.webapp.secret_key }}"
|
||||||
|
HOTPOCKET_BACKEND_ALLOWED_HOSTS="{{ hotpocket_app.backend.webapp.allowed_hosts|join(',') }}"
|
||||||
|
HOTPOCKET_BACKEND_SAVES_SAVE_ADAPTER="hotpocket_backend.apps.saves.adapters.postgres:PostgresSaveAdapter"
|
||||||
|
HOTPOCKET_BACKEND_SAVES_ASSOCIATION_ADAPTER="hotpocket_backend.apps.saves.adapters.postgres:PostgresAssociationAdapter"
|
||||||
|
{% for extra_env in hotpocket_app.backend.webapp.extra_env|default([]) %}
|
||||||
|
{{ extra_env }}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
services:
|
||||||
|
backend-webapp:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.webapp.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-webapp:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-admin:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/gunicorn"
|
||||||
|
- "-c"
|
||||||
|
- "/srv/lib/gunicorn.conf.py"
|
||||||
|
- "-b"
|
||||||
|
- "unix:///srv/run/gunicorn.sock"
|
||||||
|
- "hotpocket_backend.wsgi:application"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.admin.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_admin.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-admin:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-celery-worker:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "worker"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-Q"
|
||||||
|
- "celery,webapp"
|
||||||
|
- "-c"
|
||||||
|
- "{{ hotpocket_app.backend.celery_worker.concurrency }}"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.celery_worker.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-celery-worker:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
|
|
||||||
|
backend-celery-beat:
|
||||||
|
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:{{ hotpocket_app.backend.image_tag }}"
|
||||||
|
command:
|
||||||
|
- "/srv/venv/bin/celery"
|
||||||
|
- "-A"
|
||||||
|
- "hotpocket_backend.celery:app"
|
||||||
|
- "beat"
|
||||||
|
- "-l"
|
||||||
|
- "INFO"
|
||||||
|
- "-s"
|
||||||
|
- "/srv/run/celery-beat-schedule"
|
||||||
|
logging:
|
||||||
|
driver: "loki"
|
||||||
|
options:
|
||||||
|
loki-url: "{{ hotpocket_app.loki.url }}"
|
||||||
|
loki-external-labels: "{{ hotpocket_app.backend.celery_beat.loki.external_labels }}"
|
||||||
|
labels: "node"
|
||||||
|
labels:
|
||||||
|
node: "{{ hotpocket_app.loki.node }}"
|
||||||
|
env_file:
|
||||||
|
- "etc/backend_base.env"
|
||||||
|
- "etc/backend_webapp.env"
|
||||||
|
extra_hosts: [{% for extra_host in hotpocket_app.docker.extra_hosts %}"{{ extra_host }}"{% endfor %}]
|
||||||
|
restart: "unless-stopped"
|
||||||
|
volumes:
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/etc/backend:/srv/etc"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/lib/backend:/srv/lib/backend"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/backend-celery-beat:/srv/run"
|
||||||
|
- "{{ hotpocket_app.deployment_directory }}/run/uploads:/srv/uploads"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=hotpocket_backend.webapp
|
||||||
|
Requires=docker.service
|
||||||
|
After=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
WorkingDirectory={{ hotpocket_app.deployment_directory }}
|
||||||
|
ExecStart=/usr/bin/docker compose up -d
|
||||||
|
ExecStop=/usr/bin/docker compose down
|
||||||
|
TimeoutStartSec=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
16
deployment/hotpocket_app/roles/hotpocket_app/vars/main.yaml
Normal file
16
deployment/hotpocket_app/roles/hotpocket_app/vars/main.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
hotpocket_app_role:
|
||||||
|
env_files:
|
||||||
|
fullstack:
|
||||||
|
- "backend_admin.env"
|
||||||
|
- "backend_base.env"
|
||||||
|
- "backend_webapp.env"
|
||||||
|
aio:
|
||||||
|
- "backend_base.env"
|
||||||
|
- "backend_webapp.env"
|
||||||
|
services:
|
||||||
|
fullstack:
|
||||||
|
src: "hotpocket_app.service"
|
||||||
|
dest: "hotpocket_app.service"
|
||||||
|
aio:
|
||||||
|
src: "hotpocket_app.service"
|
||||||
|
dest: "staging_hotpocket_app.service"
|
||||||
@@ -45,11 +45,12 @@ COPY --from=deployment-build /srv/packages /srv/packages
|
|||||||
COPY --from=deployment-build /srv/venv /srv/venv
|
COPY --from=deployment-build /srv/venv /srv/venv
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/bin/*.sh /srv/bin/
|
||||||
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/deployment/gunicorn.conf.py backend/ops/deployment/gunicorn.logging.conf /srv/lib/
|
COPY --chown=$APP_USER_UID:$APP_USER_GID backend/ops/deployment/gunicorn.conf.py backend/ops/deployment/gunicorn.logging.conf /srv/lib/
|
||||||
|
COPY --chown=root:root backend/ops/etc/sudoers_app /etc/sudoers.d/app
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y libpq5 dumb-init && \
|
apt-get install -y libpq5 dumb-init sudo && \
|
||||||
apt-get clean autoclean && \
|
apt-get clean autoclean && \
|
||||||
apt-get autoremove --yes && \
|
apt-get autoremove --yes && \
|
||||||
rm -rf /var/lib/apt /var/lib/dpkg && \
|
rm -rf /var/lib/apt /var/lib/dpkg && \
|
||||||
@@ -67,6 +68,8 @@ ARG APP_USER_GID
|
|||||||
ARG IMAGE_ID
|
ARG IMAGE_ID
|
||||||
|
|
||||||
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.deployment.webapp
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_UID=${APP_USER_UID}
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_GID=${APP_USER_GID}
|
||||||
ENV HOTPOCKET_BACKEND_ENV=deployment
|
ENV HOTPOCKET_BACKEND_ENV=deployment
|
||||||
ENV HOTPOCKET_BACKEND_APP=webapp
|
ENV HOTPOCKET_BACKEND_APP=webapp
|
||||||
|
|
||||||
@@ -79,6 +82,8 @@ ARG APP_USER_GID
|
|||||||
ARG IMAGE_ID
|
ARG IMAGE_ID
|
||||||
|
|
||||||
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.aio
|
ENV DJANGO_SETTINGS_MODULE=hotpocket_backend.settings.aio
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_UID=${APP_USER_UID}
|
||||||
|
ENV HOTPOCKET_BACKEND_APP_USER_GID=${APP_USER_GID}
|
||||||
ENV HOTPOCKET_BACKEND_ENV=aio
|
ENV HOTPOCKET_BACKEND_ENV=aio
|
||||||
ENV HOTPOCKET_BACKEND_APP=webapp
|
ENV HOTPOCKET_BACKEND_APP=webapp
|
||||||
ENV HOTPOCKET_BACKEND_DEBUG=false
|
ENV HOTPOCKET_BACKEND_DEBUG=false
|
||||||
@@ -92,6 +97,7 @@ ENV HOTPOCKET_BACKEND_CELERY_IGNORE_RESULT=true
|
|||||||
ENV HOTPOCKET_BACKEND_CELERY_ALWAYS_EAGER=true
|
ENV HOTPOCKET_BACKEND_CELERY_ALWAYS_EAGER=true
|
||||||
ENV HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
ENV HOTPOCKET_BACKEND_GUNICORN_WORKERS=2
|
||||||
ENV HOTPOCKET_BACKEND_RUN_MIGRATIONS=true
|
ENV HOTPOCKET_BACKEND_RUN_MIGRATIONS=true
|
||||||
|
ENV HOTPOCKET_BACKEND_CREATE_INITIAL_ACCOUNT=true
|
||||||
ENV HOTPOCKET_BACKEND_UPLOADS_PATH=/srv/run/uploads
|
ENV HOTPOCKET_BACKEND_UPLOADS_PATH=/srv/run/uploads
|
||||||
|
|
||||||
VOLUME ["/srv/run"]
|
VOLUME ["/srv/run"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
version = '25.10.21'
|
version = '25.11.06.b0'
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from django.core.management import BaseCommand
|
|||||||
import django.db
|
import django.db
|
||||||
|
|
||||||
from hotpocket_backend.apps.accounts.models import Account
|
from hotpocket_backend.apps.accounts.models import Account
|
||||||
|
from hotpocket_backend.apps.core.conf import settings
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -17,12 +18,12 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def add_arguments(self, parser: ArgumentParser):
|
def add_arguments(self, parser: ArgumentParser):
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'username',
|
'-u', '--username', default=None,
|
||||||
help='Username for the Account',
|
help='Override username for the Account',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'password',
|
'-p', '--password', default=None,
|
||||||
help='Password for the Account',
|
help='Override Password for the Account',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-d', '--dry-run', action='store_true', default=False,
|
'-d', '--dry-run', action='store_true', default=False,
|
||||||
@@ -31,10 +32,22 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
LOGGER.debug('args=`%s` options=`%s`', args, options)
|
LOGGER.debug('args=`%s` options=`%s`', args, options)
|
||||||
username = options.get('username')
|
|
||||||
password = options.get('password')
|
|
||||||
dry_run = options.get('dry_run', False)
|
dry_run = options.get('dry_run', False)
|
||||||
|
|
||||||
|
username = options.get('username') or settings.SECRETS.INITIAL_ACCOUNT.username
|
||||||
|
if not username:
|
||||||
|
LOGGER.info('Not creating initial Account: empty `username`')
|
||||||
|
return
|
||||||
|
|
||||||
|
password = options.get('password') or settings.SECRETS.INITIAL_ACCOUNT.password
|
||||||
|
assert password, 'Unable to proceed: empty `password`'
|
||||||
|
|
||||||
|
LOGGER.debug(
|
||||||
|
'Creating initial Account: username=`%s` password=`%s`',
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
)
|
||||||
|
|
||||||
with django.db.transaction.atomic():
|
with django.db.transaction.atomic():
|
||||||
current_account = Account.objects.filter(username=username).first()
|
current_account = Account.objects.filter(username=username).first()
|
||||||
if current_account is not None:
|
if current_account is not None:
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from keep_it_secret import AbstractField, LiteralField, Secrets, SecretsField
|
from keep_it_secret import (
|
||||||
|
AbstractField,
|
||||||
|
EnvField,
|
||||||
|
LiteralField,
|
||||||
|
Secrets,
|
||||||
|
SecretsField,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DatabaseSecrets(Secrets):
|
class DatabaseSecrets(Secrets):
|
||||||
@@ -84,6 +90,19 @@ class CelerySecrets(Secrets):
|
|||||||
result_backend: str = AbstractField.new()
|
result_backend: str = AbstractField.new()
|
||||||
|
|
||||||
|
|
||||||
|
class InitialAccountSecrets(Secrets):
|
||||||
|
username: str = EnvField.new(
|
||||||
|
'HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME',
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
password: str = EnvField.new(
|
||||||
|
'HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD',
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseSecrets(Secrets):
|
class BaseSecrets(Secrets):
|
||||||
SECRET_KEY: str = AbstractField.new()
|
SECRET_KEY: str = AbstractField.new()
|
||||||
|
|
||||||
@@ -91,3 +110,4 @@ class BaseSecrets(Secrets):
|
|||||||
CELERY: CelerySecrets = SecretsField.new(CelerySecrets)
|
CELERY: CelerySecrets = SecretsField.new(CelerySecrets)
|
||||||
|
|
||||||
OIDC: OIDCSecrets = SecretsField.new(OIDCSecrets)
|
OIDC: OIDCSecrets = SecretsField.new(OIDCSecrets)
|
||||||
|
INITIAL_ACCOUNT: InitialAccountSecrets = SecretsField.new(InitialAccountSecrets)
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ MIDDLEWARE = [
|
|||||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||||
|
SESSION_COOKIE_SECURE = False
|
||||||
|
|
||||||
STORAGES['staticfiles'] = { # noqa: F405
|
STORAGES['staticfiles'] = { # noqa: F405
|
||||||
'BACKEND': 'whitenoise.storage.CompressedManifestStaticFilesStorage',
|
'BACKEND': 'whitenoise.storage.CompressedManifestStaticFilesStorage',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ STATIC_URL = 'static/'
|
|||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
LOGGING_LEVEL = os.environ.get('HOTPOCKET_BACKEND_LOGGING_LEVEL', 'INFO')
|
||||||
|
|
||||||
LOG_FORMAT = '%(asctime)s %(levelname)s [%(name)s] [%(request_id)s] (%(funcName)s:%(lineno)s) %(message)s'
|
LOG_FORMAT = '%(asctime)s %(levelname)s [%(name)s] [%(request_id)s] (%(funcName)s:%(lineno)s) %(message)s'
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
@@ -149,17 +151,17 @@ LOGGING = {
|
|||||||
'loggers': {
|
'loggers': {
|
||||||
'hotpocket_backend': {
|
'hotpocket_backend': {
|
||||||
'handlers': ['hotpocket'],
|
'handlers': ['hotpocket'],
|
||||||
'level': 'INFO',
|
'level': LOGGING_LEVEL,
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
},
|
},
|
||||||
'hotpocket_common': {
|
'hotpocket_common': {
|
||||||
'handlers': ['hotpocket'],
|
'handlers': ['hotpocket'],
|
||||||
'level': 'INFO',
|
'level': LOGGING_LEVEL,
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
},
|
},
|
||||||
'hotpocket_soa': {
|
'hotpocket_soa': {
|
||||||
'handlers': ['hotpocket'],
|
'handlers': ['hotpocket'],
|
||||||
'level': 'INFO',
|
'level': LOGGING_LEVEL,
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
},
|
},
|
||||||
'django': {
|
'django': {
|
||||||
|
|||||||
@@ -13,26 +13,21 @@ cat <<EOF
|
|||||||
|_|
|
|_|
|
||||||
production
|
production
|
||||||
|
|
||||||
HotPocket v25.10.21 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
|
HotPocket v25.11.06.b0 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
|
||||||
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
|
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
|
||||||
Licensed under Apache-2.0
|
Licensed under Apache-2.0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
export PYTHONPATH="/srv/app:$PYTHONPATH"
|
export PYTHONPATH="/srv/app:$PYTHONPATH"
|
||||||
|
|
||||||
if [ -n "${HOTPOCKET_BACKEND_RUN_MIGRATIONS}" ];then
|
echo; echo "--- Preparing the system..."
|
||||||
echo; echo "--- Running migrations..."
|
|
||||||
${VIRTUAL_ENV}/bin/python /srv/app/manage.py migrate
|
UPLOADS_PATH="${HOTPOCKET_BACKEND_UPLOADS_PATH:-/srv/uploads}"
|
||||||
|
if [ ! -d "${UPLOADS_PATH}" ];then
|
||||||
|
mkdir -p "${UPLOADS_PATH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME}" && -n "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD}" ]]; then
|
sudo /srv/bin/fix-run-uploads-permissions.sh ${HOTPOCKET_BACKEND_APP_USER_UID} "${UPLOADS_PATH}"
|
||||||
echo; echo "--- Creating initial Account..."
|
|
||||||
${VIRTUAL_ENV}/bin/python /srv/app/manage.py create_initial_account "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME}" "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${HOTPOCKET_BACKEND_ENV}" = "aio" ];then
|
|
||||||
mkdir -p "${HOTPOCKET_BACKEND_UPLOADS_PATH:-/srv/run/uploads}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo; echo "--- Running entrypoint.d parts..."
|
echo; echo "--- Running entrypoint.d parts..."
|
||||||
find "/srv/etc/entrypoint.d/" -follow -type f -print | sort -V | while read -r ENTRYPOINT_PART; do
|
find "/srv/etc/entrypoint.d/" -follow -type f -print | sort -V | while read -r ENTRYPOINT_PART; do
|
||||||
@@ -48,6 +43,16 @@ find "/srv/etc/entrypoint.d/" -follow -type f -print | sort -V | while read -r E
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -n "${HOTPOCKET_BACKEND_RUN_MIGRATIONS}" ];then
|
||||||
|
echo; echo "--- Running migrations..."
|
||||||
|
${VIRTUAL_ENV}/bin/python /srv/app/manage.py migrate
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${HOTPOCKET_BACKEND_CREATE_INITIAL_ACCOUNT}" ];then
|
||||||
|
echo; echo "--- Creating initial Account..."
|
||||||
|
${VIRTUAL_ENV}/bin/python /srv/app/manage.py create_initial_account
|
||||||
|
fi
|
||||||
|
|
||||||
echo; echo "--- Setup done, booting the app..."; echo
|
echo; echo "--- Setup done, booting the app..."; echo
|
||||||
|
|
||||||
exec /usr/bin/dumb-init "$@"
|
exec /usr/bin/dumb-init "$@"
|
||||||
|
|||||||
9
services/backend/ops/bin/fix-run-uploads-permissions.sh
Executable file
9
services/backend/ops/bin/fix-run-uploads-permissions.sh
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
echo "Fixing runtime directory permissions..."
|
||||||
|
|
||||||
|
chown $1 /srv/run || true
|
||||||
|
chmod 775 /srv/run
|
||||||
|
|
||||||
|
chown $1 $2 || true
|
||||||
|
chmod 775 $2
|
||||||
1
services/backend/ops/etc/sudoers_app
Normal file
1
services/backend/ops/etc/sudoers_app
Normal file
@@ -0,0 +1 @@
|
|||||||
|
app ALL=(root) NOPASSWD: /srv/bin/fix-run-uploads-permissions.sh
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hotpocket-backend",
|
"name": "hotpocket-backend",
|
||||||
"version": "25.10.21",
|
"version": "25.11.06.b0",
|
||||||
"description": "HotPocket Backend",
|
"description": "HotPocket Backend",
|
||||||
"main": "hotpocket_backend/apps/frontend/src/index.js",
|
"main": "hotpocket_backend/apps/frontend/src/index.js",
|
||||||
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",
|
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hotpocket-backend"
|
name = "hotpocket-backend"
|
||||||
version = "25.10.21"
|
version = "25.11.06.b0"
|
||||||
description = "HotPocket Backend"
|
description = "HotPocket Backend"
|
||||||
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|||||||
2
tasks.py
2
tasks.py
@@ -291,5 +291,5 @@ def bump_version(ctx: Context,
|
|||||||
f'inv bump-version {next_version} --build {build}',
|
f'inv bump-version {next_version} --build {build}',
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'backend' in services_to_bump:
|
if service is None:
|
||||||
tools_bump_version_task(ctx, next_version, build=build)
|
tools_bump_version_task(ctx, next_version, build=build)
|
||||||
|
|||||||
Reference in New Issue
Block a user