mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-25 20:40:36 +03:00
Setup dev and prod configurations for docker
This commit is contained in:
parent
aba28f7b39
commit
31cbb6f05a
46
README.md
46
README.md
|
@ -2,20 +2,11 @@
|
|||
React + Django based web portal for editing RSForm schemas.
|
||||
This readme file is used mostly to document project dependencies
|
||||
|
||||
|
||||
# Developer Setup Notes
|
||||
- Install Python 3.9, NodeJS, VSCode, Docker Desktop
|
||||
- copy import wheels from ConceptCore to rsconcept\backend\import
|
||||
- run rsconcept\backend\LocalEnvSetup.ps1
|
||||
- run 'npm install' in rsconcept\frontend
|
||||
- use VSCode configs in root folder to start developement
|
||||
- production: create secrets secrets\db_password.txt and django_key.txt
|
||||
- production: provide TLS certificate nginx\cert\portal-cert.pem and nginx\cert\portal-key.pem
|
||||
|
||||
# Contributing notes
|
||||
!BEFORE PUSHING INTO MAIN!
|
||||
- use Test config in VSCode to run tests before pushing commits / requests
|
||||
- !BEFORE PUSHING INTO MAIN! in rsconcept\frontend run in terminal 'npm run build' and fix all errors
|
||||
- when making major changes make sure that Docker production is building correctly. run 'docker compose -f docker-compose-prod.yml up'
|
||||
- cd rsconcept/frontend & npm run build
|
||||
- docker compose -f docker-compose-prod.yml up
|
||||
|
||||
# Frontend stack & Tooling [Vite + React + Typescript]
|
||||
<details>
|
||||
|
@ -62,11 +53,11 @@ This readme file is used mostly to document project dependencies
|
|||
<details>
|
||||
<summary>requirements</summary>
|
||||
<pre>
|
||||
- tzdata
|
||||
- django
|
||||
- djangorestframework
|
||||
- django-cors-headers
|
||||
- django-filter
|
||||
- tzdata
|
||||
- gunicorn
|
||||
- coreapi
|
||||
- psycopg2-binary
|
||||
|
@ -96,3 +87,32 @@ This readme file is used mostly to document project dependencies
|
|||
# DevOps
|
||||
- Docker compose
|
||||
- PowerShell
|
||||
- Certbot
|
||||
- Docker VSCode extension
|
||||
|
||||
# Developer Notes
|
||||
## Local build (Windows 10+)
|
||||
- this is main developers build
|
||||
- Install Python 3.9, NodeJS, VSCode, Docker Desktop
|
||||
- copy import wheels from ConceptCore to rsconcept/backend/import
|
||||
- run rsconcept/backend/LocalEnvSetup.ps1
|
||||
- run 'npm install' in rsconcept/frontend
|
||||
- use VSCode configs in root folder to start developement
|
||||
|
||||
## Developement build
|
||||
- this build does not use HTTPS and nginx for networking
|
||||
- backend and frontend debugging is supported
|
||||
- hmr (hot updates) for frontend
|
||||
- run via 'docker compose -f "docker-compose-dev.yml" up --build -d'
|
||||
- populate initial data: rsconcept/PopulateDevData.ps1 dev-portal-backend
|
||||
|
||||
## Local production build
|
||||
- this build is same as production except not using production secrets and working on localhost
|
||||
- provide TLS certificate (can be self-signed) 'nginx/cert/local-cert.pem' and 'nginx/cert/local-key.pem'
|
||||
- run via 'docker compose -f "docker-compose-prod-local.yml" up --build -d'
|
||||
- populate initial data: rsconcept/PopulateDevData.ps1 local-portal-backend
|
||||
|
||||
## Production build
|
||||
- create secrets secrets/db_password.txt and django_key.txt
|
||||
- provide TLS certificate 'nginx/cert/front-cert.pem' and 'nginx/cert/front-key.pem'
|
||||
- run via 'docker compose -f "docker-compose-prod.yml" up --build -d'
|
||||
|
|
55
docker-compose-dev.yml
Normal file
55
docker-compose-dev.yml
Normal file
|
@ -0,0 +1,55 @@
|
|||
name: dev-concept-portal
|
||||
|
||||
volumes:
|
||||
postgres_volume:
|
||||
name: "dev-portal-data"
|
||||
django_static_volume:
|
||||
name: "dev-portal-static"
|
||||
django_media_volume:
|
||||
name: "dev-portal-media"
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: dev-concept-api-net
|
||||
|
||||
services:
|
||||
frontend:
|
||||
container_name: dev-portal-frontend
|
||||
restart: always
|
||||
depends_on:
|
||||
- backend
|
||||
build:
|
||||
context: ./rsconcept/frontend
|
||||
dockerfile: Dockerfile.dev
|
||||
args:
|
||||
BUILD_TYPE: development
|
||||
ports:
|
||||
- 3002:3002
|
||||
command: npm run dev -- --host
|
||||
|
||||
|
||||
backend:
|
||||
container_name: dev-portal-backend
|
||||
restart: always
|
||||
depends_on:
|
||||
- postgresql-db
|
||||
build:
|
||||
context: ./rsconcept/backend
|
||||
env_file: ./rsconcept/backend/.env.dev
|
||||
ports:
|
||||
- 8002:8002
|
||||
volumes:
|
||||
- django_static_volume:/home/app/web/static
|
||||
- django_media_volume:/home/app/web/media
|
||||
command:
|
||||
gunicorn -w 3 project.wsgi --bind 0.0.0.0:8002
|
||||
|
||||
|
||||
postgresql-db:
|
||||
container_name: dev-portal-db
|
||||
restart: always
|
||||
image: postgres:alpine
|
||||
env_file: ./postgresql/.env.dev
|
||||
volumes:
|
||||
- postgres_volume:/var/lib/postgresql/data
|
||||
|
71
docker-compose-prod-local.yml
Normal file
71
docker-compose-prod-local.yml
Normal file
|
@ -0,0 +1,71 @@
|
|||
name: local-concept-portal
|
||||
|
||||
volumes:
|
||||
postgres_volume:
|
||||
name: "local-portal-data"
|
||||
django_static_volume:
|
||||
name: "local-portal-static"
|
||||
django_media_volume:
|
||||
name: "local-portal-media"
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: local-concept-api-net
|
||||
|
||||
services:
|
||||
frontend:
|
||||
container_name: local-portal-frontend
|
||||
restart: always
|
||||
depends_on:
|
||||
- backend
|
||||
build:
|
||||
context: ./rsconcept/frontend
|
||||
args:
|
||||
BUILD_TYPE: production.local
|
||||
expose:
|
||||
- 3001
|
||||
command: serve -s /home/node -l 3001
|
||||
|
||||
|
||||
backend:
|
||||
container_name: local-portal-backend
|
||||
restart: always
|
||||
depends_on:
|
||||
- postgresql-db
|
||||
build:
|
||||
context: ./rsconcept/backend
|
||||
env_file: ./rsconcept/backend/.env.prod.local
|
||||
expose:
|
||||
- 8001
|
||||
volumes:
|
||||
- django_static_volume:/home/app/web/static
|
||||
- django_media_volume:/home/app/web/media
|
||||
command:
|
||||
gunicorn -w 3 project.wsgi --bind 0.0.0.0:8001
|
||||
|
||||
|
||||
postgresql-db:
|
||||
container_name: local-portal-db
|
||||
restart: always
|
||||
image: postgres:alpine
|
||||
env_file: ./postgresql/.env.prod.local
|
||||
volumes:
|
||||
- postgres_volume:/var/lib/postgresql/data
|
||||
|
||||
|
||||
nginx:
|
||||
container_name: local-portal-router
|
||||
restart: always
|
||||
build:
|
||||
context: ./nginx
|
||||
args:
|
||||
BUILD_TYPE: production.local
|
||||
ports:
|
||||
- 8001:8001
|
||||
- 3001:3001
|
||||
depends_on:
|
||||
- backend
|
||||
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
|
||||
volumes:
|
||||
- django_static_volume:/var/www/static
|
||||
- django_media_volume:/var/www/media
|
|
@ -26,6 +26,8 @@ services:
|
|||
- backend
|
||||
build:
|
||||
context: ./rsconcept/frontend
|
||||
args:
|
||||
BUILD_TYPE: production
|
||||
expose:
|
||||
- 3000
|
||||
command: serve -s /home/node -l 3000
|
||||
|
@ -72,6 +74,8 @@ services:
|
|||
restart: always
|
||||
build:
|
||||
context: ./nginx
|
||||
args:
|
||||
BUILD_TYPE: production
|
||||
ports:
|
||||
- 8000:8000
|
||||
- 3000:3000
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
FROM nginx:stable-alpine3.17-slim
|
||||
ARG BUILD_TYPE=production
|
||||
|
||||
# Сopу nginx configuration to the proxy-server
|
||||
COPY ./default.conf /etc/nginx/conf.d/default.conf
|
||||
COPY ./$BUILD_TYPE.conf /etc/nginx/conf.d/default.conf
|
||||
COPY ./cert/* /etc/ssl/private/
|
|
@ -10,7 +10,7 @@ server {
|
|||
listen 8000 ssl;
|
||||
ssl_certificate /etc/ssl/private/front-cert.pem;
|
||||
ssl_certificate_key /etc/ssl/private/front-key.pem;
|
||||
server_name dev.concept.ru www.dev.concept.ru portal.acconcept.ru www.portal.acconcept.ru api.portal.acconcept.ru www.api.portal.acconcept.ru mail.acconcept.ru www.mail.acconcept.ru;
|
||||
server_name dev.concept.ru www.dev.concept.ru portal.acconcept.ru www.portal.acconcept.ru api.portal.acconcept.ru www.api.portal.acconcept.ru;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
@ -30,7 +30,7 @@ server {
|
|||
listen 3000 ssl;
|
||||
ssl_certificate /etc/ssl/private/front-cert.pem;
|
||||
ssl_certificate_key /etc/ssl/private/front-key.pem;
|
||||
server_name dev.concept.ru www.dev.concept.ru portal.acconcept.ru www.portal.acconcept.ru mail.acconcept.ru www.mail.acconcept.ru;
|
||||
server_name dev.concept.ru www.dev.concept.ru portal.acconcept.ru www.portal.acconcept.ru;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
41
nginx/production.local.conf
Normal file
41
nginx/production.local.conf
Normal file
|
@ -0,0 +1,41 @@
|
|||
upstream innerdjango {
|
||||
server backend:8001;
|
||||
}
|
||||
|
||||
upstream innerreact {
|
||||
server frontend:3001;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8001 ssl;
|
||||
ssl_certificate /etc/ssl/private/local-cert.pem;
|
||||
ssl_certificate_key /etc/ssl/private/local-key.pem;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://innerdjango;
|
||||
proxy_redirect default;
|
||||
}
|
||||
location /static/ {
|
||||
alias /var/www/static/;
|
||||
}
|
||||
location /media/ {
|
||||
alias /var/www/media/;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 3001 ssl;
|
||||
ssl_certificate /etc/ssl/private/local-cert.pem;
|
||||
ssl_certificate_key /etc/ssl/private/local-key.pem;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://innerreact;
|
||||
proxy_redirect default;
|
||||
}
|
||||
}
|
5
postgresql/.env.dev
Normal file
5
postgresql/.env.dev
Normal file
|
@ -0,0 +1,5 @@
|
|||
# WARNING! This config does not use 'real' production values for secrets
|
||||
# DO NOT use PRODUCTION LOCAL build for deployment!
|
||||
POSTGRES_USER=portal-admin
|
||||
POSTGRES_DB=portal-db
|
||||
POSTGRES_PASSWORD=78ACF6C4F3
|
5
postgresql/.env.prod.local
Normal file
5
postgresql/.env.prod.local
Normal file
|
@ -0,0 +1,5 @@
|
|||
# WARNING! This config does not use 'real' production values for secrets
|
||||
# DO NOT use PRODUCTION LOCAL build for deployment!
|
||||
POSTGRES_USER=portal-admin
|
||||
POSTGRES_DB=portal-db
|
||||
POSTGRES_PASSWORD=78ACF6C4F3
|
13
rsconcept/PopulateDevData.ps1
Normal file
13
rsconcept/PopulateDevData.ps1
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Initialize database !
|
||||
# FOR DEVELOPEMENT BUILDS ONLY!
|
||||
$container= Read-Host -Prompt "Enter backend container name: "
|
||||
|
||||
docker exec -it $container python manage.py loaddata fixtures/InitialData.json
|
||||
|
||||
docker exec `
|
||||
-e DJANGO_SUPERUSER_USERNAME=admin `
|
||||
-e DJANGO_SUPERUSER_PASSWORD=1234 `
|
||||
-e DJANGO_SUPERUSER_EMAIL=admin@admin.com `
|
||||
-it $container python manage.py createsuperuser --noinput
|
||||
|
||||
pause
|
27
rsconcept/backend/.env.dev
Normal file
27
rsconcept/backend/.env.dev
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Application settings
|
||||
# WARNING! This config does not use 'real' production values for secrets
|
||||
# DO NOT use PRODUCTION LOCAL build for deployment!
|
||||
SECRET_KEY=s-55j!5jlan=x%8-6m1qnst^7s6nwby4dx@vei)5w8t)3_=mv1
|
||||
ALLOWED_HOSTS=localhost
|
||||
CSRF_TRUSTED_ORIGINS=http://localhost:3002;http://localhost:8002
|
||||
CORS_ALLOWED_ORIGINS=http://localhost:3002
|
||||
|
||||
|
||||
# File locations
|
||||
STATIC_ROOT=/home/app/web/static
|
||||
MEDIA_ROOT=/home/app/web/media
|
||||
|
||||
|
||||
# Database settings
|
||||
DB_ENGINE=django.db.backends.postgresql_psycopg2
|
||||
DB_NAME=portal-db
|
||||
DB_USER=portal-admin
|
||||
DB_HOST=postgresql-db
|
||||
DB_PORT=5432
|
||||
DB_PASSWORD=78ACF6C4F3
|
||||
|
||||
|
||||
# Debug settings
|
||||
DEBUG=1
|
||||
PYTHONDEVMODE=1
|
||||
PYTHONTRACEMALLOC=1
|
|
@ -1,5 +1,6 @@
|
|||
# Application settings
|
||||
|
||||
# SECRET_KEY=
|
||||
ALLOWED_HOSTS=portal.acconcept.ru;dev.concept.ru
|
||||
CSRF_TRUSTED_ORIGINS=https://dev.concept.ru:3000;https://dev.concept.ru:8000;https://portal.acconcept.ru;https://portal.acconcept.ru:8081;https://portal.acconcept.ru:8082
|
||||
CORS_ALLOWED_ORIGINS=https://dev.concept.ru:3000;https://portal.acconcept.ru;https://portal.acconcept.ru:8081
|
||||
|
@ -16,6 +17,7 @@ DB_NAME=portal-db
|
|||
DB_USER=portal-admin
|
||||
DB_HOST=postgresql-db
|
||||
DB_PORT=5432
|
||||
# DB_PASSWORD=
|
||||
|
||||
|
||||
# Debug settings
|
||||
|
|
27
rsconcept/backend/.env.prod.local
Normal file
27
rsconcept/backend/.env.prod.local
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Application settings
|
||||
# WARNING! This config does not use 'real' production values for secrets
|
||||
# DO NOT use PRODUCTION LOCAL build for deployment!
|
||||
SECRET_KEY=s-55j!5jlan=x%8-6m1qnst^7s6nwby4dx@vei)5w8t)3_=mv1
|
||||
ALLOWED_HOSTS=localhost
|
||||
CSRF_TRUSTED_ORIGINS=https://localhost:3001;https://localhost:8001
|
||||
CORS_ALLOWED_ORIGINS=https://localhost:3001
|
||||
|
||||
|
||||
# File locations
|
||||
STATIC_ROOT=/home/app/web/static
|
||||
MEDIA_ROOT=/home/app/web/media
|
||||
|
||||
|
||||
# Database settings
|
||||
DB_ENGINE=django.db.backends.postgresql_psycopg2
|
||||
DB_NAME=portal-db
|
||||
DB_USER=portal-admin
|
||||
DB_HOST=postgresql-db
|
||||
DB_PORT=5432
|
||||
DB_PASSWORD=78ACF6C4F3
|
||||
|
||||
|
||||
# Debug settings
|
||||
DEBUG=0
|
||||
PYTHONDEVMODE=0
|
||||
PYTHONTRACEMALLOC=0
|
|
@ -1,3 +1,4 @@
|
|||
# Dev specific
|
||||
.gitignore
|
||||
node_modules
|
||||
.env.local
|
5
rsconcept/frontend/.env.local
Normal file
5
rsconcept/frontend/.env.local
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Local build config
|
||||
|
||||
VITE_PORTAL_BACKEND=http://localhost:8000
|
||||
VITE_PORTAL_FRONT_PORT=3000
|
||||
VITE_PORTAL_FRONT_HTTPS=false
|
|
@ -5,11 +5,14 @@ RUN apt-get update -qq && \
|
|||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ======= Build =======
|
||||
ARG BUILD_TYPE=production
|
||||
FROM node-base as builder
|
||||
|
||||
WORKDIR /result
|
||||
|
||||
COPY ./ ./
|
||||
COPY ./env/.env.$BUILD_TYPE ./
|
||||
RUN rm -rf ./env
|
||||
RUN npm install
|
||||
ENV NODE_ENV production
|
||||
RUN npm run build
|
||||
|
|
17
rsconcept/frontend/Dockerfile.dev
Normal file
17
rsconcept/frontend/Dockerfile.dev
Normal file
|
@ -0,0 +1,17 @@
|
|||
# ======== Multi-stage base ==========
|
||||
FROM node:bullseye-slim as node-base
|
||||
RUN apt-get update -qq && \
|
||||
apt-get upgrade -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# ========= Server =======
|
||||
FROM node-base as product-server
|
||||
ARG BUILD_TYPE=production
|
||||
|
||||
WORKDIR /home
|
||||
|
||||
COPY ./ ./
|
||||
COPY ./env/.env.$BUILD_TYPE ./
|
||||
RUN rm -rf ./env
|
||||
|
||||
RUN npm install
|
5
rsconcept/frontend/env/.env.development
vendored
Normal file
5
rsconcept/frontend/env/.env.development
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Frontend public settings: Production Local
|
||||
|
||||
VITE_PORTAL_BACKEND=http://localhost:8002
|
||||
VITE_PORTAL_FRONT_PORT=3002
|
||||
VITE_PORTAL_FRONT_HTTPS=false
|
5
rsconcept/frontend/env/.env.production
vendored
Normal file
5
rsconcept/frontend/env/.env.production
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Frontend public settings: Production
|
||||
|
||||
VITE_PORTAL_BACKEND=https://portal.acconcept.ru:8082
|
||||
VITE_PORTAL_FRONT_PORT=3000
|
||||
VITE_PORTAL_FRONT_HTTPS=true
|
6
rsconcept/frontend/env/.env.production.local
vendored
Normal file
6
rsconcept/frontend/env/.env.production.local
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Frontend public settings: Production Local
|
||||
|
||||
VITE_PORTAL_BACKEND=https://localhost:8001
|
||||
VITE_PORTAL_FRONT_PORT=3001
|
||||
VITE_PORTAL_FRONT_HTTPS=true
|
||||
|
|
@ -1,16 +1,7 @@
|
|||
// Constants
|
||||
const prod = {
|
||||
backend: 'https://portal.acconcept.ru:8082',
|
||||
// backend: 'https://dev.concept.ru:8000',
|
||||
// backend: 'https://localhost:8000',
|
||||
// backend: 'https://api.portal.concept.ru',
|
||||
export const config = {
|
||||
backend: import.meta.env.VITE_PORTAL_BACKEND as string
|
||||
};
|
||||
|
||||
const dev = {
|
||||
backend: 'http://localhost:8000',
|
||||
};
|
||||
|
||||
export const config = process.env.NODE_ENV === 'production' ? prod : dev;
|
||||
export const TIMEOUT_UI_REFRESH = 100;
|
||||
|
||||
export const youtube = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
|
||||
import { dependencies } from './package.json'
|
||||
|
||||
|
@ -14,10 +14,16 @@ function renderChunks(deps: Record<string, string>) {
|
|||
}
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
export default (({ mode }: { mode: string }) => {
|
||||
process.env = {...process.env, ...loadEnv(mode, process.cwd())};
|
||||
const enableHttps = process.env.VITE_PORTAL_FRONT_HTTPS === 'true';
|
||||
return defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 3000
|
||||
port: Number(process.env.VITE_PORTAL_FRONT_PORT),
|
||||
|
||||
// NOTE: https is not used for dev builds currently
|
||||
https: enableHttps,
|
||||
},
|
||||
build: {
|
||||
chunkSizeWarningLimit: 4000, // KB
|
||||
|
@ -25,9 +31,11 @@ export default defineConfig({
|
|||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
// Load chunks for dependencies separately
|
||||
...renderChunks(dependencies),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user