diff --git a/.gitea/workflows/deploy-prod.yaml b/.gitea/workflows/deploy-prod.yaml new file mode 100644 index 0000000..6569086 --- /dev/null +++ b/.gitea/workflows/deploy-prod.yaml @@ -0,0 +1,65 @@ +name: Frontend Build and Deploy to Production + +on: + workflow_dispatch: {} + +env: + REGISTRY_HOST: git.ivanch.me + IMAGE_FRONTEND: ${{ env.REGISTRY_HOST }}/ivanch/opencand.ui + # ─────────────────────────────────────────────────────────────────────────── + DEPLOY_USER: ${{ secrets.LIVE_USERNAME }} + DEPLOY_HOST: ${{ secrets.LIVE_HOST }} + DEPLOY_PATH: ${{ secrets.LIVE_PROJECT_DIR }} + +jobs: + build_and_deploy: + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v2 + + - name: Log in to Container Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" \ + | docker login "${{ env.REGISTRY_HOST }}" \ + -u "${{ secrets.REGISTRY_USERNAME }}" \ + --password-stdin + + - name: Build and Push Frontend Image + run: | + TAG=latest + + docker build \ + --build-arg VITE_API_BASE_URL="https://api.opencand.ivanch.me" \ + --file OpenCand.UI.dockerfile \ + -t "${{ env.IMAGE_FRONTEND }}:${TAG}" \ + . + + docker push "${{ env.IMAGE_FRONTEND }}:${TAG}" + + - name: Set up SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.LIVE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + + # Add the host to known_hosts so SSH does not prompt + ssh-keyscan -H "${{ env.DEPLOY_HOST }}" >> ~/.ssh/known_hosts + + - name: Deploy to Production Server + run: | + TAG=latest + + ssh "${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }}" << 'EOF' + cd "${{ env.DEPLOY_PATH }}" + + # Replace the “image:” line for the frontend service + # sed -i \ + # "s|image: .*/frontend:.*|image: ${{ env.IMAGE_FRONTEND }}:${TAG}|g" \ + # docker-compose.yml + + # Pull only the new frontend image, then restart that service + docker compose pull frontend + docker compose up frontend -d + EOF diff --git a/.gitea/workflows/main.yaml b/.gitea/workflows/main.yaml index b719c11..c2585a6 100644 --- a/.gitea/workflows/main.yaml +++ b/.gitea/workflows/main.yaml @@ -1,65 +1,19 @@ name: Frontend Build and Deploy on: - workflow_dispatch: {} - -env: - REGISTRY_HOST: git.ivanch.me - IMAGE_FRONTEND: ${{ env.REGISTRY_HOST }}/ivanch/opencand.ui - # ─────────────────────────────────────────────────────────────────────────── - DEPLOY_USER: ${{ secrets.LIVE_USERNAME }} - DEPLOY_HOST: ${{ secrets.LIVE_HOST }} - DEPLOY_PATH: ${{ secrets.LIVE_PROJECT_DIR }} + push: + branches: + - main jobs: - build_and_deploy: + build: runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v2 - - name: Log in to Container Registry + - name: Build Frontend Image run: | - echo "${{ secrets.REGISTRY_PASSWORD }}" \ - | docker login "${{ env.REGISTRY_HOST }}" \ - -u "${{ secrets.REGISTRY_USERNAME }}" \ - --password-stdin - - - name: Build and Push Frontend Image - run: | - TAG=latest - - docker build \ - --build-arg VITE_API_BASE_URL="https://api.opencand.ivanch.me" \ - --file OpenCand.UI.dockerfile \ - -t "${{ env.IMAGE_FRONTEND }}:${TAG}" \ - . - - docker push "${{ env.IMAGE_FRONTEND }}:${TAG}" - - - name: Set up SSH - run: | - mkdir -p ~/.ssh - echo "${{ secrets.LIVE_KEY }}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - - # Add the host to known_hosts so SSH does not prompt - ssh-keyscan -H "${{ env.DEPLOY_HOST }}" >> ~/.ssh/known_hosts - - - name: Deploy to Production Server - run: | - TAG=latest - - ssh "${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }}" << 'EOF' - cd "${{ env.DEPLOY_PATH }}" - - # Replace the “image:” line for the frontend service - # sed -i \ - # "s|image: .*/frontend:.*|image: ${{ env.IMAGE_FRONTEND }}:${TAG}|g" \ - # docker-compose.yml - - # Pull only the new frontend image, then restart that service - docker compose pull frontend - docker compose up frontend -d - EOF + npm install + npm run build diff --git a/OpenCand.UI.dockerfile b/OpenCand.UI.dockerfile index 0690054..a76841b 100644 --- a/OpenCand.UI.dockerfile +++ b/OpenCand.UI.dockerfile @@ -17,6 +17,8 @@ RUN yarn build FROM nginx:stable-alpine # Remove default nginx html RUN rm -rf /usr/share/nginx/html/* +# Replace default nginx.conf +COPY nginx.conf /etc/nginx/nginx.conf # Copy our built files into nginx’s html folder COPY --from=builder /app/dist /usr/share/nginx/html diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..85c55cf --- /dev/null +++ b/nginx.conf @@ -0,0 +1,30 @@ +worker_processes 1; +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # If the file or folder doesn’t exist, fall back to index.html + location / { + try_files $uri $uri/ /index.html; + } + + # (Optional) Static asset caching + location ~* \.(?:css|js|svg|png|jpg|jpeg|gif|ico)$ { + expires 30d; + add_header Cache-Control "public, max-age=2592000"; + } + } +}