Steve/EV Dashboard/nginx 도커파일 및 설정파일 추가
This commit is contained in:
35
ev-charging-backend/.env
Normal file
35
ev-charging-backend/.env
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# ── 데이터베이스 ──
|
||||||
|
POSTGRES_DB=ev_charging
|
||||||
|
POSTGRES_USER=evuser
|
||||||
|
POSTGRES_PASSWORD=evpass1234
|
||||||
|
POSTGRES_HOST=postgres
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
# ── Redis ──
|
||||||
|
REDIS_HOST=redis
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
# ── Steve OCPP 서버 ──
|
||||||
|
STEVE_BASE_URL=https://s1.byunc.com/steve
|
||||||
|
STEVE_API_USER=admin
|
||||||
|
STEVE_API_PASSWORD=changeme
|
||||||
|
|
||||||
|
# ── 토스페이먼츠 ──
|
||||||
|
TOSS_CLIENT_KEY=test_ck_Poxy1XQL8RYmzR9JgL5lr7nO5Wml
|
||||||
|
TOSS_SECRET_KEY=test_sk_ZLKGPx4M3M90lvAvzx1n3BaWypv1
|
||||||
|
#TOSS_CLIENT_KEY=test_ck_xxxxxxxxxx
|
||||||
|
#TOSS_SECRET_KEY=test_sk_xxxxxxxxxx
|
||||||
|
|
||||||
|
# ── 요금 설정 (원/kWh) ──
|
||||||
|
ELECTRICITY_RATE=120
|
||||||
|
SERVICE_MARGIN=50
|
||||||
|
|
||||||
|
# ── JWT ──
|
||||||
|
JWT_SECRET=your-super-secret-key-change-this
|
||||||
|
JWT_ALGORITHM=HS256
|
||||||
|
JWT_EXPIRE_MINUTES=1440
|
||||||
|
|
||||||
|
# ── 서버 ──
|
||||||
|
SERVER_HOST=0.0.0.0
|
||||||
|
SERVER_PORT=8000
|
||||||
|
DEBUG=true
|
||||||
15
ev-charging-backend/Dockerfile
Normal file
15
ev-charging-backend/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
# 시스템 패키지
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
gcc libpq-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY ./app /code/app
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||||
10
ev-charging-backend/Dockerfile.proxy
Executable file
10
ev-charging-backend/Dockerfile.proxy
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir websockets aiohttp
|
||||||
|
|
||||||
|
COPY entrypoint-proxy.sh /code/
|
||||||
|
RUN chmod +x /code/entrypoint-proxy.sh
|
||||||
|
|
||||||
|
CMD ["/code/entrypoint-proxy.sh"]
|
||||||
84
ev-charging-backend/docker-compose.yml
Normal file
84
ev-charging-backend/docker-compose.yml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
services:
|
||||||
|
# ── FastAPI 백엔드 ──
|
||||||
|
api:
|
||||||
|
build: .
|
||||||
|
container_name: ev-api
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ./app:/code/app
|
||||||
|
- ./dashboard.html:/code/dashboard.html:ro
|
||||||
|
- ./simulator.html:/code/simulator.html:ro
|
||||||
|
networks:
|
||||||
|
- ev-net
|
||||||
|
|
||||||
|
# ── OCPP 프록시 서버 ──
|
||||||
|
proxy:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.proxy
|
||||||
|
container_name: ev-proxy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "9002:9002"
|
||||||
|
- "9003:9003"
|
||||||
|
volumes:
|
||||||
|
- ./ocpp_proxy_server.py:/code/ocpp_proxy_server.py:ro
|
||||||
|
- ./proxy_control.html:/code/proxy_control.html:ro
|
||||||
|
- proxy_logs:/code/ocpp_logs
|
||||||
|
- proxy_config:/code/config
|
||||||
|
networks:
|
||||||
|
- ev-net
|
||||||
|
|
||||||
|
# ── PostgreSQL ──
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: ev-postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-ev_charging}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-evuser}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-evpass1234}
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-evuser}"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- ev-net
|
||||||
|
|
||||||
|
# ── Redis ──
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: ev-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6375:6379"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- ev-net
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
proxy_logs:
|
||||||
|
proxy_config:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ev-net:
|
||||||
|
driver: bridge
|
||||||
89
nginx/s1.byunc.com.conf
Normal file
89
nginx/s1.byunc.com.conf
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
server {
|
||||||
|
#listen [::]:80;
|
||||||
|
#root /var/www/html/mysite.com;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
server_name s1.byunc.com;
|
||||||
|
|
||||||
|
#error_log /var/log/nginx/mysite.com_error.log;
|
||||||
|
#access_log /var/log/nginx/mysite.com_access.log;
|
||||||
|
|
||||||
|
client_max_body_size 16G;
|
||||||
|
|
||||||
|
location = / {
|
||||||
|
return 302 /steve/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /steve {
|
||||||
|
proxy_pass http://192.168.0.126:8180;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ── FastAPI 대시보드 + API ──
|
||||||
|
location = /dashboard {
|
||||||
|
proxy_pass http://192.168.0.126:8000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://192.168.0.126:8000;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://192.168.0.126:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket 전용 설정 (핵심)
|
||||||
|
location /steve/websocket {
|
||||||
|
proxy_pass http://192.168.0.126:8180;
|
||||||
|
|
||||||
|
# WebSocket 업그레이드 헤더
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
# WebSocket 타임아웃 (충전 중 끊기지 않게)
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
proxy_send_timeout 86400s;
|
||||||
|
proxy_connect_timeout 86400s;
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
proxy_pass http://192.168.0.126:8180;
|
||||||
|
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;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
proxy_send_timeout 86400s;
|
||||||
|
proxy_connect_timeout 86400s;
|
||||||
|
}
|
||||||
|
listen 443 ssl; # managed by Certbot
|
||||||
|
ssl_certificate /etc/letsencrypt/live/s1.byunc.com/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/s1.byunc.com/privkey.pem; # managed by Certbot
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
if ($host = s1.byunc.com) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
} # managed by Certbot
|
||||||
|
|
||||||
|
|
||||||
|
server_name s1.byunc.com;
|
||||||
|
listen 80;
|
||||||
|
return 404; # managed by Certbot
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
25
steve/Dockerfile
Normal file
25
steve/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
FROM eclipse-temurin:21-jdk
|
||||||
|
|
||||||
|
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
|
||||||
|
|
||||||
|
MAINTAINER Ling Li
|
||||||
|
|
||||||
|
# Download and install dockerize.
|
||||||
|
# Needed so the web container will wait for MariaDB to start.
|
||||||
|
ENV DOCKERIZE_VERSION v0.19.0
|
||||||
|
RUN curl -sfL https://github.com/powerman/dockerize/releases/download/"$DOCKERIZE_VERSION"/dockerize-`uname -s`-`uname -m` | install /dev/stdin /usr/local/bin/dockerize
|
||||||
|
|
||||||
|
EXPOSE 8180
|
||||||
|
EXPOSE 8443
|
||||||
|
WORKDIR /code
|
||||||
|
|
||||||
|
VOLUME ["/code"]
|
||||||
|
|
||||||
|
# Copy the application's code
|
||||||
|
COPY . /code
|
||||||
|
|
||||||
|
# Wait for the db to startup(via dockerize), then
|
||||||
|
# Build and run steve, requires a db to be available on port 3306
|
||||||
|
CMD dockerize -wait tcp://mariadb:3306 -timeout 60s && \
|
||||||
|
./mvnw clean package -Pdocker,mariadb -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" && \
|
||||||
|
java -XX:MaxRAMPercentage=85 -jar target/steve.war
|
||||||
47
steve/JettyConfiguration.java
Normal file
47
steve/JettyConfiguration.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* SteVe - SteckdosenVerwaltung - https://github.com/steve-community/steve
|
||||||
|
* Copyright (C) 2013-2026 SteVe Community Team
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package de.rwth.idsg.steve.config;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpCompliance;
|
||||||
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.springframework.boot.jetty.JettyServerCustomizer;
|
||||||
|
import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory;
|
||||||
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class JettyConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public WebServerFactoryCustomizer<JettyServletWebServerFactory> jettyHttpComplianceCustomizer() {
|
||||||
|
return factory -> factory.addServerCustomizers((JettyServerCustomizer) server -> {
|
||||||
|
for (var connector : server.getConnectors()) {
|
||||||
|
if (connector instanceof ServerConnector serverConnector) {
|
||||||
|
for (var cf : serverConnector.getConnectionFactories()) {
|
||||||
|
if (cf instanceof HttpConnectionFactory httpCF) {
|
||||||
|
httpCF.getHttpConfiguration().setHttpCompliance(HttpCompliance.RFC7230_LEGACY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
66
steve/application-docker.properties
Normal file
66
steve/application-docker.properties
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# Just to be backwards compatible with previous versions, this is set to "steve",
|
||||||
|
# since there might be already configured chargepoints expecting the older path.
|
||||||
|
# Otherwise, might as well be changed to something else or be left empty.
|
||||||
|
#
|
||||||
|
context.path = steve
|
||||||
|
|
||||||
|
# Database configuration
|
||||||
|
#
|
||||||
|
db.ip = mariadb
|
||||||
|
db.port = 3306
|
||||||
|
db.schema = stevedb
|
||||||
|
db.user = steve
|
||||||
|
db.password = changeme
|
||||||
|
|
||||||
|
# Credentials for Web interface access
|
||||||
|
#
|
||||||
|
auth.user = admin
|
||||||
|
auth.password = 1234
|
||||||
|
|
||||||
|
# The header key and value for Web API access using API key authorization.
|
||||||
|
# Both must be set for Web APIs to be enabled. Otherwise, we will block all calls.
|
||||||
|
#
|
||||||
|
webapi.key = STEVE-API-KEY
|
||||||
|
webapi.value =
|
||||||
|
|
||||||
|
# Jetty configuration
|
||||||
|
#
|
||||||
|
server.host = 0.0.0.0
|
||||||
|
server.gzip.enabled = false
|
||||||
|
|
||||||
|
# Jetty HTTP configuration
|
||||||
|
#
|
||||||
|
http.enabled = true
|
||||||
|
http.port = 8180
|
||||||
|
|
||||||
|
# Jetty HTTPS configuration
|
||||||
|
#
|
||||||
|
https.enabled = false
|
||||||
|
https.port = 8443
|
||||||
|
keystore.path =
|
||||||
|
keystore.password =
|
||||||
|
|
||||||
|
# When the WebSocket/Json charge point opens more than one WebSocket connection,
|
||||||
|
# we need a mechanism/strategy to select one of them for outgoing requests.
|
||||||
|
# For allowed values see de.rwth.idsg.steve.ocpp.ws.custom.WsSessionSelectStrategyEnum.
|
||||||
|
#
|
||||||
|
ws.session.select.strategy = ALWAYS_LAST
|
||||||
|
|
||||||
|
# if BootNotification messages arrive (SOAP) or WebSocket connection attempts are made (JSON) from unknown charging
|
||||||
|
# stations, we reject these charging stations, because stations with these chargeBoxIds were NOT inserted into database
|
||||||
|
# beforehand. by setting this property to true, this behaviour can be modified to automatically insert unknown
|
||||||
|
# stations into database and accept their requests.
|
||||||
|
#
|
||||||
|
# CAUTION: setting this property to true is very dangerous, because we will accept EVERY BootNotification or WebSocket
|
||||||
|
# connection attempt from ANY sender as long as the sender knows the URL and sends a valid message.
|
||||||
|
#
|
||||||
|
auto.register.unknown.stations = false
|
||||||
|
|
||||||
|
# if this field is set, it will take precedence over the default regex we are using in
|
||||||
|
# de.rwth.idsg.steve.web.validation.ChargeBoxIdValidator.REGEX to validate the format of the chargeBoxId values
|
||||||
|
#
|
||||||
|
charge-box-id.validation.regex =
|
||||||
|
|
||||||
|
### DO NOT MODIFY ###
|
||||||
|
db.sql.logging = false
|
||||||
|
profile = prod
|
||||||
31
steve/docker-compose.yml
Normal file
31
steve/docker-compose.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
version: "3.0"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db-data:
|
||||||
|
external: false
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mariadb:10.11.16
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- 3307:3306
|
||||||
|
environment:
|
||||||
|
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
||||||
|
MYSQL_DATABASE: stevedb
|
||||||
|
MYSQL_USER: steve
|
||||||
|
MYSQL_PASSWORD: changeme
|
||||||
|
app:
|
||||||
|
restart: unless-stopped
|
||||||
|
build: .
|
||||||
|
links:
|
||||||
|
- "db:mariadb"
|
||||||
|
volumes:
|
||||||
|
- .:/code
|
||||||
|
ports:
|
||||||
|
- "8180:8180"
|
||||||
|
- "8445:8443"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
Reference in New Issue
Block a user