Compare commits

..

7 Commits

Author SHA1 Message Date
ae96b79fb2 adding reverse proxy with ssl
All checks were successful
Build and Deploy Demo App / build-and-deploy (push) Successful in 33s
2025-11-26 00:59:21 +03:30
acb7df5cf9 improved index
All checks were successful
Build and Deploy Demo App / build-and-deploy (push) Successful in 1m56s
2025-11-25 18:56:49 +03:30
cf8df36d4f improved project
All checks were successful
Build and Deploy Demo App / build-and-deploy (push) Successful in 50s
2025-11-25 18:52:52 +03:30
d00626a62c improved project
Some checks failed
Build and Deploy Demo App / build-and-deploy (push) Failing after 18s
2025-11-25 18:49:09 +03:30
a4a588be94 deploying cicd demo app
All checks were successful
Build and Deploy Demo App / build-and-deploy (push) Successful in 1m42s
2025-11-25 18:20:52 +03:30
aba3c9cb98 edit runner label
All checks were successful
Hello from Gitea Actions / hello (push) Successful in 1m3s
2025-11-25 11:41:50 +03:30
beea66532d edit runner label 2025-11-25 11:37:05 +03:30
7 changed files with 209 additions and 12 deletions

View File

@@ -1,20 +1,64 @@
name: Hello from Gitea Actions
name: Build and Deploy Demo App
on:
push: # run on every push
push:
branches:
- main # adjust if your default branch is different
- main
jobs:
hello:
runs-on: devops # must match your runner's label
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Say hello
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
run: docker build -t demo-app:latest .
- name: Save Docker image to tar
run: docker save demo-app:latest > demo-app.tar
- name: Set up SSH
run: |
echo "Hello from Gitea Actions!"
echo "Runner: ${{ runner.name }}"
echo "Repo: ${{ gitea.repository }}"
apt update && apt install -y openssh-client
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-keyscan -p ${{ secrets.SERVER_PORT }} ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Copy files to server via SCP
run: |
scp -o StrictHostKeyChecking=no -P ${{ secrets.SERVER_PORT }} demo-app.tar ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.DEPLOY_PATH }}demo-app.tar
scp -o StrictHostKeyChecking=no -P ${{ secrets.SERVER_PORT }} docker-compose.yml ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.DEPLOY_PATH }}docker-compose.yml
scp -o StrictHostKeyChecking=no -P ${{ secrets.SERVER_PORT }} -r nginx_user_conf.d ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.DEPLOY_PATH }}nginx_user_conf.d
- name: Deploy on server via SSH
run: |
ssh -o StrictHostKeyChecking=no -p ${{ secrets.SERVER_PORT }} ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << EOF
cd ${{ secrets.DEPLOY_PATH }}
# Check and install Docker if not present (Ubuntu/Debian assumed)
if ! command -v docker &> /dev/null; then
sudo apt update -y
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \$(. /etc/os-release && echo "\$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update -y
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker
fi
# Check and install Docker Compose if not present
if ! command -v docker-compose &> /dev/null; then
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-\$(uname -s)-\$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
fi
# Load image and deploy with Compose
docker load -i demo-app.tar
docker-compose down || true # Graceful stop
docker-compose up -d
# Cleanup
rm demo-app.tar
EOF

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
COPY templates ./templates
EXPOSE 5000
CMD ["python", "app.py"]

12
app.py Normal file
View File

@@ -0,0 +1,12 @@
from flask import Flask, render_template
from flask_bootstrap import Bootstrap5 # Updated import for Bootstrap 5 support
app = Flask(__name__)
bootstrap = Bootstrap5(app)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

24
docker-compose.yml Normal file
View File

@@ -0,0 +1,24 @@
services:
app:
image: demo-app:latest
container_name: demo-app
restart: unless-stopped
nginx:
image: jonasal/nginx-certbot:latest
container_name: demo-nginx
restart: unless-stopped
ports:
- 8008:80
- 4433:443
environment:
- CERTBOT_EMAIL=your@email.com
- ENVSUBST_TEMPLATE_SUFFIX=.tmpl # Enables template processing if needed
volumes:
- ./nginx_user_conf.d:/etc/nginx/user_conf.d:ro
- letsencrypt:/etc/letsencrypt
depends_on:
- app
volumes:
letsencrypt:

View File

@@ -0,0 +1,17 @@
server {
listen 80;
listen 443 ssl;
server_name demo.networkwizard.xyz;
# SSL config handled by the container image
location / {
proxy_pass http://app:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Redirect HTTP to HTTPS (handled automatically by the image after certs are obtained)
}

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
flask==3.0.3
bootstrap-flask==2.5.0

89
templates/index.html Normal file
View File

@@ -0,0 +1,89 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Professional Demo Site</title>
<!-- Bootstrap CSS -->
{{ bootstrap.load_css() }}
<style>
body { padding-top: 60px; } /* Space for fixed navbar */
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="/">Demo Pro Site</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#features">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#about">About</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<!-- Hero Section -->
<div class="bg-primary text-white py-5 mt-4 rounded text-center">
<h1 class="display-4">Welcome to the Professional Demo Site</h1>
<p class="lead">This is a realistic, Bootstrap-powered Flask application for demonstration purposes. It features responsive design and modern UI elements.</p>
<a class="btn btn-light btn-lg" href="#features" role="button">Learn More</a>
</div>
<!-- Features Section -->
<section id="features" class="py-5">
<h2 class="text-center mb-4">Key Features</h2>
<div class="row">
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Responsive Design</h5>
<p class="card-text">Adapts seamlessly to mobile, tablet, and desktop devices.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Modern UI</h5>
<p class="card-text">Uses Bootstrap 5 for clean, professional styling.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">Easy Deployment</h5>
<p class="card-text">Containerized with Docker for quick setup on any server.</p>
</div>
</div>
</div>
</div>
</section>
<!-- About Section -->
<section id="about" class="py-5 bg-light">
<h2 class="text-center mb-4">About This Demo</h2>
<p class="text-center">This site serves as a starting point for building more complex web applications. Extend it with databases, APIs, or user authentication as needed.</p>
</section>
</div>
<!-- Bootstrap JS -->
{{ bootstrap.load_js() }}
</body>
</html>