ci: Migrate deployment to Docker-based infrastructure
Some checks failed
CI / Test & Build (18.x) (push) Has been cancelled
CI / Test & Build (20.x) (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
Build Production / Build Production Artifacts (push) Has been cancelled

This commit is contained in:
debudebuye 2026-02-26 11:45:46 +03:00
parent 9c7e33499a
commit 529b4f9d37
6 changed files with 73 additions and 198 deletions

View File

@ -1,4 +1,4 @@
name: Deploy to Production name: Build Production
on: on:
push: push:
@ -6,8 +6,8 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
deploy: build:
name: Deploy to Netlify/Vercel name: Build Production Artifacts
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -33,35 +33,20 @@ jobs:
VITE_ENV: production VITE_ENV: production
VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }} VITE_SENTRY_DSN: ${{ secrets.VITE_SENTRY_DSN }}
# Option 1: Deploy to Netlify - name: Upload production artifacts
- name: Deploy to Netlify uses: actions/upload-artifact@v4
uses: nwtgck/actions-netlify@v3.0
with: with:
publish-dir: './dist' name: production-build
production-branch: main path: dist/
github-token: ${{ secrets.GITHUB_TOKEN }} retention-days: 30
deploy-message: "Deploy from GitHub Actions"
enable-pull-request-comment: true
enable-commit-comment: true
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
timeout-minutes: 5
# Option 2: Deploy to Vercel (comment out Netlify if using this) - name: Build Docker image
# - name: Deploy to Vercel run: docker build -t yaltopia-admin:${{ github.sha }} .
# uses: amondnet/vercel-action@v25
# with:
# vercel-token: ${{ secrets.VERCEL_TOKEN }}
# vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
# vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
# vercel-args: '--prod'
# working-directory: ./
- name: Notify deployment success - name: Build success notification
if: success() if: success()
run: echo "Deployment successful!" run: echo "Production build successful!"
- name: Notify deployment failure - name: Build failure notification
if: failure() if: failure()
run: echo "Deployment failed!" run: echo "Production build failed!"

View File

@ -103,59 +103,39 @@ npm run preview
## Deployment ## Deployment
### Static Hosting (Netlify, Vercel, etc.) ### Docker Deployment (Recommended)
1. Build the Docker image:
```bash
docker build -t yaltopia-admin:latest .
```
2. Run the container:
```bash
docker run -p 8080:80 yaltopia-admin:latest
```
3. Deploy to your cloud provider (AWS, GCP, Azure, DigitalOcean, etc.)
### Traditional VPS Deployment
1. Build the application: `npm run build:prod` 1. Build the application: `npm run build:prod`
2. Deploy the `dist` directory 2. Copy the `dist` directory to your web server
3. Configure environment variables in your hosting platform 3. Configure nginx or Apache to serve the static files
4. Set up redirects for SPA routing (see below) 4. Set up redirects for SPA routing (see nginx.conf example)
### SPA Routing Configuration ### SPA Routing Configuration
For proper routing, add a redirect rule: For proper routing with nginx, use the included `nginx.conf` file or add this configuration:
**Netlify** (`netlify.toml`):
```toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
```
**Vercel** (`vercel.json`):
```json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
```
### Docker Deployment
Create a `Dockerfile`:
```dockerfile
FROM node:18-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build:prod
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
Create `nginx.conf`:
```nginx ```nginx
server { location / {
listen 80; try_files $uri $uri/ /index.html;
server_name _; }
root /usr/share/nginx/html; ```
index index.html; The project includes a `Dockerfile` and `nginx.conf` for containerized deployment.
See [DEPLOYMENT.md](dev-docs/DEPLOYMENT.md) for detailed deployment instructions.
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;

View File

@ -51,47 +51,7 @@
## Deployment Options ## Deployment Options
### Option 1: Vercel (Recommended for Quick Deploy) ### Option 1: Docker + Cloud Provider (Recommended)
1. Install Vercel CLI:
```bash
npm i -g vercel
```
2. Login to Vercel:
```bash
vercel login
```
3. Deploy:
```bash
vercel --prod
```
4. Set environment variables in Vercel dashboard:
- Go to Project Settings → Environment Variables
- Add `VITE_API_URL` with your production API URL
### Option 2: Netlify
1. Install Netlify CLI:
```bash
npm i -g netlify-cli
```
2. Login:
```bash
netlify login
```
3. Deploy:
```bash
netlify deploy --prod
```
4. Set environment variables in Netlify dashboard
### Option 3: Docker + Cloud Provider
1. Build Docker image: 1. Build Docker image:
```bash ```bash
@ -121,7 +81,7 @@ docker push account-id.dkr.ecr.region.amazonaws.com/yaltopia-admin:latest
- Azure Container Instances - Azure Container Instances
- DigitalOcean App Platform - DigitalOcean App Platform
### Option 4: Traditional VPS (Ubuntu/Debian) ### Option 2: Traditional VPS (Ubuntu/Debian)
1. SSH into your server 1. SSH into your server
@ -181,26 +141,42 @@ sudo cp -r dist/* /var/www/html/
### GitHub Actions (Automated) ### GitHub Actions (Automated)
The `.github/workflows/ci.yml` file is configured for CI. The `.github/workflows/ci.yml` file is configured for CI, and `.github/workflows/deploy.yml` builds production artifacts.
For CD, add deployment step: For automated deployment, you can extend the workflow to:
1. **Push Docker image to registry:**
```yaml ```yaml
- name: Deploy to Vercel - name: Login to Docker Registry
if: github.ref == 'refs/heads/main' uses: docker/login-action@v3
run: | with:
npm i -g vercel registry: ${{ secrets.DOCKER_REGISTRY }}
vercel --prod --token=${{ secrets.VERCEL_TOKEN }} username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKER_REGISTRY }}/yaltopia-admin:latest
${{ secrets.DOCKER_REGISTRY }}/yaltopia-admin:${{ github.sha }}
``` ```
Or for Netlify: 2. **Deploy to your server via SSH:**
```yaml ```yaml
- name: Deploy to Netlify - name: Deploy to production server
if: github.ref == 'refs/heads/main' uses: appleboy/ssh-action@v1.0.0
run: | with:
npm i -g netlify-cli host: ${{ secrets.DEPLOY_HOST }}
netlify deploy --prod --auth=${{ secrets.NETLIFY_AUTH_TOKEN }} --site=${{ secrets.NETLIFY_SITE_ID }} username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
cd /opt/yaltopia-admin
docker pull ${{ secrets.DOCKER_REGISTRY }}/yaltopia-admin:latest
docker-compose down
docker-compose up -d
``` ```
## Troubleshooting ## Troubleshooting

View File

@ -29,7 +29,7 @@ Testing setup and practices:
### [Deployment Guide](./DEPLOYMENT.md) ### [Deployment Guide](./DEPLOYMENT.md)
Production deployment: Production deployment:
- Pre-deployment checklist - Pre-deployment checklist
- Deployment options (Vercel, Netlify, Docker) - Deployment options (Docker, VPS)
- Environment configuration - Environment configuration
- CI/CD setup - CI/CD setup

View File

@ -1,24 +0,0 @@
[build]
command = "npm run build:prod"
publish = "dist"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[build.environment]
NODE_VERSION = "18"
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "SAMEORIGIN"
X-Content-Type-Options = "nosniff"
X-XSS-Protection = "1; mode=block"
Referrer-Policy = "strict-origin-when-cross-origin"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"

View File

@ -1,42 +0,0 @@
{
"buildCommand": "npm run build:prod",
"outputDirectory": "dist",
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
}
]
},
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}