remake architecture.
This commit is contained in:
+3
-1
@@ -1,2 +1,4 @@
|
|||||||
project_context.txt
|
project_context.txt
|
||||||
shagram.db
|
shagram.db
|
||||||
|
deploy/shagram/nginx/certs/*.pem
|
||||||
|
deploy/shagram/.env
|
||||||
Vendored
+22
-12
@@ -1,35 +1,45 @@
|
|||||||
pipeline{
|
pipeline{
|
||||||
agent any
|
agent { label 'docker' }
|
||||||
options {
|
options {
|
||||||
skipDefaultCheckout()
|
skipDefaultCheckout()
|
||||||
}
|
}
|
||||||
|
environment {
|
||||||
|
SRC_DIR = "/opt/shagram/src/shagram"
|
||||||
|
DEPLOY_DIR = "/opt/shagram/deploy/shagram"
|
||||||
|
IMAGE_NAME = "shagram"
|
||||||
|
}
|
||||||
stages{
|
stages{
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
deleteDir()
|
dir(env.SRC_DIR) {
|
||||||
git url: 'https://github.com/emil28092005/shagram.git', branch: 'main'
|
deleteDir()
|
||||||
|
git url: 'https://github.com/emil28092005/shagram.git', branch: 'main'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
echo 'Building shagram...'
|
dir(env.SRC_DIR) {
|
||||||
sh 'docker build -t shagram-shagram:latest .'
|
echo 'Building shagram...'
|
||||||
|
sh 'docker build -t ${IMAGE_NAME}:${GIT_COMMIT} .'
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Test') {
|
stage('Test') {
|
||||||
steps {
|
steps {
|
||||||
echo 'Testing...'
|
echo 'Testing...'
|
||||||
sh 'docker run --rm shagram-shagram:latest sqlite3 /app/shagram.db "SELECT 1;" || true'
|
sh 'docker run --rm ${IMAGE_NAME}:${GIT_COMMIT} sqlite3 --version'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Deploy') {
|
stage('Deploy') {
|
||||||
steps {
|
steps {
|
||||||
echo 'Deploying...'
|
dir(env.DEPLOY_DIR) {
|
||||||
sh '''
|
echo 'Deploying...'
|
||||||
docker compose down || true
|
sh 'printf "APP_IMAGE=%s\\n" "${IMAGE_NAME}:${GIT_COMMIT}" > .env'
|
||||||
docker compose up -d
|
sh 'docker compose up -d'
|
||||||
docker compose ps
|
sh 'docker compose ps'
|
||||||
'''
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"shagram/internal/api"
|
"shagram/internal/api"
|
||||||
"shagram/internal/db"
|
"shagram/internal/db"
|
||||||
"shagram/internal/models"
|
"shagram/internal/models"
|
||||||
@@ -12,7 +13,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
database, err := db.NewDB("/app/data/shagram.db")
|
dbPath := os.Getenv("DATABASE_PATH")
|
||||||
|
if dbPath == "" {
|
||||||
|
dbPath = "/app/data/shagram.db"
|
||||||
|
}
|
||||||
|
database, err := db.NewDB(dbPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
services:
|
||||||
|
shagram:
|
||||||
|
image: ${APP_IMAGE}
|
||||||
|
container_name: shagram-app
|
||||||
|
environment:
|
||||||
|
- DATABASE_PATH=/app/data/shagram.db
|
||||||
|
volumes:
|
||||||
|
- shagram_data:/app/data
|
||||||
|
expose:
|
||||||
|
- "8080"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: shagram-nginx
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
- ./nginx/certs:/etc/nginx/certs:ro
|
||||||
|
depends_on:
|
||||||
|
- shagram
|
||||||
|
volumes:
|
||||||
|
shagram_data:
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# TLS Certificates for Nginx (Development / Self-Signed)
|
||||||
|
|
||||||
|
In production, TLS certificates are typically issued by a trusted Certificate Authority (for example, via Let’s Encrypt).
|
||||||
|
For local development and demo environments, a self-signed certificate can be used.
|
||||||
|
|
||||||
|
## Generate a self-signed certificate (Linux/macOS)
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p deploy/shagram/nginx/certs
|
||||||
|
|
||||||
|
openssl req -x509 -newkey rsa:4096 \
|
||||||
|
-keyout deploy/shagram/nginx/certs/key.pem \
|
||||||
|
-out deploy/shagram/nginx/certs/cert.pem \
|
||||||
|
-sha256 -days 365 -nodes \
|
||||||
|
-subj "/C=RU/ST=Moscow/L=Korolyov/O=Shagram/CN=localhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
```bash
|
||||||
|
openssl x509 -in deploy/shagram/nginx/certs/cert.pem -noout -text | head
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
The Nginx configuration expects:
|
||||||
|
- `deploy/shagram/nginx/certs/cert.pem`
|
||||||
|
- `deploy/shagram/nginx/certs/key.pem`
|
||||||
|
|
||||||
|
Start the deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd deploy/shagram
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
services:
|
|
||||||
jenkins:
|
|
||||||
image: jenkins/jenkins:lts-jdk17
|
|
||||||
container_name: jenkins
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
- "50000:50000"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- /usr/bin/docker:/usr/bin/docker
|
|
||||||
- /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins:ro
|
|
||||||
- jenkins_home:/var/jenkins_home
|
|
||||||
- /opt/shagram:/workspace
|
|
||||||
environment:
|
|
||||||
- DOCKER_HOST=unix:///var/run/docker.sock
|
|
||||||
user: root
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
jenkins_home:
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
services:
|
|
||||||
shagram:
|
|
||||||
build: .
|
|
||||||
ports:
|
|
||||||
- "8080"
|
|
||||||
volumes:
|
|
||||||
- ./data:/app/data
|
|
||||||
- ./static:/app/static
|
|
||||||
- ./migrations:/app/migrations
|
|
||||||
environment:
|
|
||||||
- DATABASE_PATH=/app/shagram.db
|
|
||||||
container_name: shagram-app
|
|
||||||
|
|
||||||
nginx:
|
|
||||||
image: nginx:alpine
|
|
||||||
ports:
|
|
||||||
- "80:80"
|
|
||||||
- "443:443"
|
|
||||||
volumes:
|
|
||||||
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
|
|
||||||
- ./nginx/certs:/etc/nginx/certs
|
|
||||||
depends_on:
|
|
||||||
- shagram
|
|
||||||
container_name: shagram-nginx
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# Jenkins (Controller + Docker Agent) Setup (Docker Compose)
|
||||||
|
|
||||||
|
This directory contains a minimal Jenkins setup using a dedicated **controller** and a separate inbound **agent** intended for Docker-based workloads.
|
||||||
|
|
||||||
|
The goal is to keep the controller responsible for orchestration and configuration, while all builds run on the agent labeled `docker`.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
- Docker Engine installed on the host
|
||||||
|
- Docker Compose available as `docker compose`
|
||||||
|
- A host directory `/opt/shagram` (used by pipelines as a shared location for source code and deployment files)
|
||||||
|
|
||||||
|
## Start Jenkins
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd infra/jenkins
|
||||||
|
docker compose up -d
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
Jenkins UI will be available at:
|
||||||
|
|
||||||
|
- http://<server-ip>:8080
|
||||||
|
|
||||||
|
### Initial admin password
|
||||||
|
Retrieve the initial password with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it jenkins-controller cat /var/jenkins_home/secrets/initialAdminPassword
|
||||||
|
```
|
||||||
|
|
||||||
|
## Disable builds on the built-in node (Executors = 0)
|
||||||
|
To ensure builds do not run on the controller:
|
||||||
|
|
||||||
|
1. Open Jenkins UI
|
||||||
|
2. Go to: **Manage Jenkins → Manage Nodes and Clouds**
|
||||||
|
3. Open **Built-In Node → Configure**
|
||||||
|
4. Set **Number of executors** to `0`
|
||||||
|
5. Save
|
||||||
|
|
||||||
|
## Create an inbound agent node (docker-agent)
|
||||||
|
Create a dedicated node for running pipelines:
|
||||||
|
|
||||||
|
1. Go to: **Manage Jenkins → Manage Nodes and Clouds → New Node**
|
||||||
|
2. Set:
|
||||||
|
- **Node name**: `docker-agent`
|
||||||
|
- **Type**: Permanent Agent
|
||||||
|
- **Remote root directory**: `/home/jenkins/agent`
|
||||||
|
- **Labels**: `docker`
|
||||||
|
- **Usage**: Only build jobs with label expressions matching this node
|
||||||
|
3. Save
|
||||||
|
|
||||||
|
After saving, open the agent page:
|
||||||
|
|
||||||
|
- **Manage Nodes and Clouds → docker-agent**
|
||||||
|
|
||||||
|
On that page, Jenkins provides the inbound connection details, including the **secret** required by the inbound agent container.
|
||||||
|
|
||||||
|
## Configure the agent secret in Compose
|
||||||
|
Edit `infra/jenkins/compose.yaml` and replace:
|
||||||
|
|
||||||
|
- `JENKINS_SECRET=__PASTE_ME__`
|
||||||
|
|
||||||
|
with the real secret value shown on the `docker-agent` node page.
|
||||||
|
|
||||||
|
Restart only the agent container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --force-recreate jenkins-agent-docker
|
||||||
|
docker logs -f jenkins-agent-docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
- In Jenkins UI: **Manage Nodes and Clouds**, the node `docker-agent` should be **Online**
|
||||||
|
- Any pipeline using `agent { label 'docker' }` should execute on this agent
|
||||||
|
|
||||||
|
## Security note
|
||||||
|
The Docker agent container mounts `/var/run/docker.sock`, which effectively grants high-level control over the Docker host. Use this setup only in trusted environments and limit access to Jenkins accordingly.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
services:
|
||||||
|
jenkins-controller:
|
||||||
|
image: jenkins/jenkins:lts-jdk17
|
||||||
|
container_name: jenkins-controller
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- jenkins_home:/var/jenkins_home
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
jenkins-agent-docker:
|
||||||
|
image: jenkins/inbound-agent:latest-jdk17
|
||||||
|
container_name: jenkins-agent-docker
|
||||||
|
environment:
|
||||||
|
- JENKINS_URL=http://jenkins-controller:8080
|
||||||
|
- JENKINS_AGENT_NAME=docker-agent
|
||||||
|
- JENKINS_SECRET=__PASTE_ME__
|
||||||
|
- AGENT_WORKDIR=/home/jenkins/agent
|
||||||
|
volumes:
|
||||||
|
- agent_workdir:/home/jenkins/agent
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /usr/bin/docker:/usr/bin/docker
|
||||||
|
- /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins:ro
|
||||||
|
- /opt/shagram:/opt/shagram
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- jenkins-controller
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
jenkins_home:
|
||||||
|
agent_workdir:
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDjzCCAnegAwIBAgIUG1Qc10mXTy5+Zuh1COAK6fqAl34wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwVzELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzERMA8GA1UEBwwIS29y
|
|
||||||
b2x5b3YxEDAOBgNVBAoMB1NoYWdyYW0xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0y
|
|
||||||
NjAxMTQwMTMxNDhaFw0yNzAxMTQwMTMxNDhaMFcxCzAJBgNVBAYTAlJVMQ8wDQYD
|
|
||||||
VQQIDAZNb3Njb3cxETAPBgNVBAcMCEtvcm9seW92MRAwDgYDVQQKDAdTaGFncmFt
|
|
||||||
MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
|
||||||
AoIBAQDLOB4WybryG6Cc4yU+2PPrLiM/tt15HMVp0TgcA277vofYFd90IArihbmG
|
|
||||||
KEaKYyZplUzxk55RRNS6BaAroZb0AWEg8cOid83gbnuKKaIUhjz/CDADPnnRWynb
|
|
||||||
PHjVuvIBtPLgyunbtB6U7a6JLP2nA8XaTcDFtLrhy8PTKFZ9fLRBXzxW8ZvNnL4i
|
|
||||||
FSLQYe851dOfJ1m0HwA/meK8QWfYn01O8zprleSMo+HPIudRR6ySnx/Cy3LuAcqM
|
|
||||||
sjttf6EFWs9XTiAOIbKC4M8VbOrfZjXFz45ljD0tZNziJ2g61lmdJAV8ElwZ6SDP
|
|
||||||
fGTwGjWj5Qx9Lg7qdFqjVyE0QFBJAgMBAAGjUzBRMB0GA1UdDgQWBBSd7S5Xngb4
|
|
||||||
9eeBbmTCslblkWClRDAfBgNVHSMEGDAWgBSd7S5Xngb49eeBbmTCslblkWClRDAP
|
|
||||||
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA8Lx0PAhfYRuRYuQxV
|
|
||||||
EyU4pmQ6JuAPl3gxVKHY6bFGMYooSRr5Nw/YulfPucxTKHtVlgY/l0kwofmTUh3B
|
|
||||||
Df1tulFCCmBW4zbl6cHd7TVSEJBkV7R9AqAC49ni8mVhmo3uPuARFa+mR8ATrF4y
|
|
||||||
LWlO/2n7F5g+093CqOG3b4O76PlqAl6L/z/Z+UBoMVEyiPgfxAztucsBn7oOaQwG
|
|
||||||
g6ohX2kosC2uRsc1bAofHWW0u3tFY0i6oiI7XPF9REuWJOiDlN2PsDMXhSG5xeLj
|
|
||||||
e7LUOQsNXB5deAfUFxbtEDCnEDzyp+GxXwZ0iPsJOzm2ccL6XdDzucCuR/NtuhGf
|
|
||||||
KwpD
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLOB4WybryG6Cc
|
|
||||||
4yU+2PPrLiM/tt15HMVp0TgcA277vofYFd90IArihbmGKEaKYyZplUzxk55RRNS6
|
|
||||||
BaAroZb0AWEg8cOid83gbnuKKaIUhjz/CDADPnnRWynbPHjVuvIBtPLgyunbtB6U
|
|
||||||
7a6JLP2nA8XaTcDFtLrhy8PTKFZ9fLRBXzxW8ZvNnL4iFSLQYe851dOfJ1m0HwA/
|
|
||||||
meK8QWfYn01O8zprleSMo+HPIudRR6ySnx/Cy3LuAcqMsjttf6EFWs9XTiAOIbKC
|
|
||||||
4M8VbOrfZjXFz45ljD0tZNziJ2g61lmdJAV8ElwZ6SDPfGTwGjWj5Qx9Lg7qdFqj
|
|
||||||
VyE0QFBJAgMBAAECggEALgf0UtOXd6M35omSBHIWkBknjVVRxc71TYKBS+EgOMA/
|
|
||||||
23ua3Z4rcQN60k9ZqRuL1iMmJls6Y2yspcVD8lYcEAGm+1Qf7PNnrBRCgflrt+vv
|
|
||||||
MZJsc7OpWrlkWf9Q3JLHogjXcgEsZyJdwfyzielpvDS/0nLFvVKyeRZTcUdEDhCz
|
|
||||||
MoY3tqcZVwq1k+CsW5Z8C1DZaEwgwhEXNGPgfX7R86FSNwlNmcTKJG/YHb9xBA84
|
|
||||||
O109pfe9PsQnYB9Lw+CNPHl1v6wIMRlVZZMFPevBJq+r9d8iN6dsX7c4oR8SXDDS
|
|
||||||
4Shux9RNE8XyD6HOTK+QuEvJmZmPIFjnlVZIsVkpHQKBgQD5bfeh7En+VPdHFGTg
|
|
||||||
+0o1ZSYrfvErak8zP7DoLZF4EY6CK20uZ8ou09ebWXZQfC37PliOSMJyDG70PuXc
|
|
||||||
Rh/TfnUPkPbmyRrvQi+MAsIjCEYGk2iiMQvSVs099AB6oAQetyPm2AcT4HeGNaLM
|
|
||||||
m1gurXTCelV0yT7oL7IhI6AqRQKBgQDQkoenTQ1nnvA4ghN253c+mbJWvTX+lbo9
|
|
||||||
WicOAxmA9gp/VN7NErXbgr5FcMwPtT+yLDqDgSjLp2T9ClYt/laWcO/KYwrnP9o5
|
|
||||||
DTeSB+biEAd3GHJLWJApY/dmFZey5uza+hXvlTdVCUgvFJYGgHw/Dg5E+jvUwrNT
|
|
||||||
MNN/OnpQNQKBgAtxxz3vuIlp3pqtTd+gyAvhIzo1rd0fGJkyX+yXQqhurco9MdpC
|
|
||||||
Ot2hLLBdD3er6vQvLSMCJaHT/jdIt4U+1nD+yWI4dYurSIgX0lSrP7sZwxTEKLXg
|
|
||||||
aDlzcCFak7cMpoO+RXBvEwwPbYyD439d1VL29HeD423jWfaPUa4Bk3S9AoGAWGdj
|
|
||||||
PBQ6tEr3wtvPaDyfnFcE8iLsueW4tLx7hULnEnQ26tWMQhvGHS6De2dd9uJ6Bwkc
|
|
||||||
HBUot3lSIra45HHDPazM1lm4i1/THQ9vGGRlBjiJEX+5Ihp9sC2A9TH9xISArCgI
|
|
||||||
GC6E73QptlrhZAwdnZRVlAMETR/hZkdxvaGJqmkCgYEAzHpqhLMFwOOvDr5Ya2DW
|
|
||||||
5IGSCohsNBRvPKLSXlMIT1yMfRStsp5qQrZq2Oj2xXX7Jk3jf+1lU3ZQ5O6bI6br
|
|
||||||
9MhrVKu6qI8YS3OtSDPAUOzPw1zu4yaKyCO0eNghY51PTZd3A3JA8Uh9Si7OCryD
|
|
||||||
iHnkhUQ1iasZLdnubyVUuh0=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Reference in New Issue
Block a user