자체 호스팅 서버를 통해 사이트를 제공하고 강좌를 판매하세요.
sserver는 최소한의 오버헤드로 개인 github 저장소에서 강좌 및 관련 블로그/정적 콘텐츠를 호스팅하기 위한 간단한 헤드리스 서버입니다.
기본적으로 https를 제공하므로 인증서 설치/관리를 처리할 필요가 없습니다. 콘텐츠를 github에서 자동으로 동기화하므로 콘텐츠를 서버에 업로드할 필요가 없습니다. 또한 콘텐츠 작업 흐름에 영향을 주지 않고 간단한 구성 파일로 프리미엄 콘텐츠를 지원합니다. 예를 들어, Hugo와 같은 정적 사이트 생성기를 사용하는 경우 구성 파일에 지정하여 프리미엄 콘텐츠를 공개적으로 숨길 수 있습니다. 스트라이프 통합 기능이 있어 프리미엄 콘텐츠를 판매할 수 있습니다. 사용자 추가/인증을 위한 사용자 관리 기능이 내장되어 있습니다. 또한 관리 API가 있어 사이트의 주문/사용자를 모니터링할 수 있습니다.
다음은 사용 방법에 대한 몇 가지 예입니다. 사용하기 전에 SS_<> 환경 변수를 설정했는지 확인하세요.
export SS_GITHUB_TOKEN=<github_token>
export SS_STRIPE_TOKEN=<stripe_token>
export SS_SMTP_FROM=<email_id>
export SS_SMTP_USER=<smtp_username>
export SS_SMTP_PWD=<smtp_password>
export SS_SMTP_HOST=<smtp_host_address>
export SS_SMTP_PORT=<smtp_port>
export SS_ADMIN_EMAIL=<admin_email>
export SS_ADMIN_PWD=<admin_password_for_sserver>
./sserver -repo "https://github.com/newbeelearn/sserver.git"
저장소의 루트 디렉터리에는 index.html 및 ssconfig.toml이 있어야 합니다. Hugo/jekyll 등의 정적 사이트 생성기를 사용하는 경우 저장소에는 생성된 사이트가 포함되어야 합니다. (기본적으로 루트에 index.html이 있습니다.)
./sserver -repo "https://github.com/newbeelearn/sserver.git?folder=public"
저장소는 콘텐츠를 제공하려는 폴더에 index.html이 있어야 하며, 일반적으로hugo/jekyll 등의 정적 사이트 생성기가 사용되는 경우 공개됩니다. 루트 디렉터리에 ssconfig.toml이 있어야 합니다.
./sserver -repo "https://github.com/newbeelearn/sserver.git?ref=test-config"
Branch의 루트 디렉터리에는 index.html 및 ssconfig.toml이 있어야 합니다. Hugo/jekyll 등의 정적 사이트 생성기를 사용하는 경우 브랜치에는 생성된 사이트가 포함되어야 합니다. (기본적으로 루트에 index.html이 있습니다.)
./sserver -repo "https://github.com/newbeelearn/sserver.git?domain=example.com"
저장소의 루트 디렉터리에 index.html 및 ssconfig.toml이 있어야 합니다. 사이트가 제공되는 도메인에 대한 액세스 서버는 443 포트에 바인딩할 수 있는 권한이 있어야 합니다. 이는 다음 명령을 사용하여 수행할 수 있습니다.
sudo setcap 'cap_net_bind_service=+ep' sserver
./sserver -repo "file:///workspace/projects/newbeelearn.com/sserver"
저장소의 루트 디렉터리에는 index.html 및 ssconfig.toml이 있어야 합니다. 로컬 파일의 경우에도 폴더/도메인 등의 모든 옵션을 지정할 수 있습니다.
샘플 ssconfig.toml은 아래에서 찾을 수 있습니다.
# specify the site
[site]
# period to check for new content
syncinterval = "@every 12h"
# product/course details
[[site.prod]]
name = "course1"
# path from root, this will be accessible to users who have bought the course
path = "courses/course1"
# can be draft/active, buying functionality will be enabled when status is active
status = "active"
# unique identifier for the course
sku = "prod-course-1"
# price in cents
price = 10000
# currency
currency = "USD"
sserver는 실행되는 위치에서 "wwwss" 디렉터리를 생성합니다.
drwxrwxr-x 2 test test 4096 Nov 30 17:04 a
drwxrwxr-x 8 test test 4096 Nov 30 17:04 b
drwxrwxr-x 2 test test 4096 Nov 30 17:04 certs
drwxrwxr-x 2 test test 4096 Nov 30 17:04 logs
-rw-rw-r-- 1 test test 527483 Nov 30 17:04 tmp.zip
-rw-rw-r-- 1 test test 49152 Nov 30 17:05 ssapp.db
구성 파일은 판매하려는 제품/강좌뿐만 아니라 사이트 동기화 빈도와 같은 일부 서버 매개변수를 지정하는 데 사용됩니다.
샘플 ssconfig.toml 파일은 아래와 같습니다.
#specify the site
[site]
#period to check for new content default is 12 hours
syncinterval = "@every 12h"
[[site.prod]]
name = "course1"
path = "courses/course1"
status = "active"
sku = "prod-course-1"
price = 10000
currency = "USD"
모든 API 엔드포인트는 콘텐츠 제공에 사용되는 도메인을 기준으로 합니다. 즉, 도메인이 example.com이고 API가 /api/v1/product/list
인 경우 요청은 https://example.com/api/v1/product/list입니다.
역할 계층 구조는 다음과 같습니다. admin > user > guest guest가 액세스할 수 있는 모든 API는 user도 액세스할 수 있고 사용자가 액세스할 수 있는 모든 API는 admin도 액세스할 수 있습니다. 사용자/관리자에 액세스하려면 로그인 후 얻은 API의 세션 쿠키를 각 요청과 함께 제공해야 합니다. 연습하면 브라우저에서 처리됩니다.
설명 | 요구 | 역할 |
---|---|---|
사용자 등록 | POST /api/v1/user/register | 손님 |
로그인 사용자 | POST /api/v1/user/login | 손님 |
로그아웃 사용자 | GET /api/v1/user/logout | 손님 |
사용자 확인 | GET /api/v1/user/verify/:id | 손님 |
사용자 비밀번호 재설정 | POST /api/v1/user/reset | 손님 |
제품 목록 가져오기 | GET /api/v1/product/list | 손님 |
주문 생성 | POST /api/v1/order/id | 손님 |
순서 수정 | PUT /api/v1/order/id | 사용자 |
결제 주문 | POST /api/v1/order/checkout | 사용자 |
주문 ID로 주문 받기 | GET /api/v1/order/id/:id | 사용자 |
사용자별 모든 주문 가져오기 | GET /api/v1/order/id/list | 사용자 |
사용자 비밀번호 변경 | POST /api/v1/user/changepwd | 사용자 |
모든 주문 받기 | GET /api/v1/order/list | 관리자 |
모든 사용자 가져오기 | GET /api/v1/user/list | 관리자 |
이메일과 비밀번호로 새로운 사용자를 등록하세요. SMTP 서버 설정이 설정된 경우, 인증번호 등록 시 사용한 이메일로 메일을 발송합니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/register'
-H 'Content-Type: application/x-www-form-urlencoded'
-X POST
--data-raw 'email=stripe%40newbeelearn.com&password=test&confirm-password=test&remember=on'
예시 응답
{"status":"success"}
이메일과 비밀번호로 사용자를 로그인하세요. "postlogin" 필드가 구성 파일에 설정되지 않은 경우 json을 반환하고, 그렇지 않으면 "postlogin"에 지정된 페이지로 리디렉션됩니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/login'
-H 'Content-Type: application/x-www-form-urlencoded'
-X POST
--data-raw 'email=admin%40example.com&password=admin'
예시 응답
{
"data": {
"user_id": "1",
"username": ""
},
"msg": "user found",
"status": "success"
}
로그인한 사용자를 로그아웃하고 홈페이지로 리디렉션합니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/logout'
-H 'Cookie: session_id=9e8b22a3-15ac-442f-bf65-15c37dbfc889; max-age=300; path=/; secure; SameSite=Lax'
예시 응답
<!doctype html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>
도메인이 설정되어 있는 경우 URL을 전송하고, 도메인이 설정되지 않은 경우 확인 API 뒤에 추가해야 하는 코드를 전송하여 등록된 사용자의 이메일을 확인합니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/verify/cafj5grn0gpog1j3a0m0'
예시 응답
{"status":"success"}
사용자 비밀번호를 재설정하고 로그인을 위한 새 임시 코드를 보냅니다. 사용자는 다음 로그인 시 이 코드를 사용해야 하며 비밀번호를 변경해야 합니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/reset'
-H 'Content-Type: application/x-www-form-urlencoded'
-X POST
--data-raw 'email=stripe%40newbeelearn.com'
예시 응답
{
"data": null,
"msg": "password reset successful",
"status": "success"
}
웹사이트에 등록된 모든 제품을 구매하세요. 쿼리로 "한계" 및 "오프셋"을 사용합니다. 쿼리가 설정되지 않은 경우 제한의 기본값은 10으로 설정되고 오프셋은 0으로 설정됩니다.
예시 요청
curl 'http://localhost:54545/api/v1/product/list?limit=1&offset=0'
예시 응답
{
"data": [
{
"prd_id": 1,
"prd_name": "course1",
"sku": "prod-course-1",
"permalink": "users/list/",
"price": 10000,
"currency": "USD",
"period": 365,
"status": "active"
}
],
"msg": "Order found",
"status": "success"
}
"line_item"
필드에 나열된 제품으로 새 주문을 생성합니다. 요청은 유효한 JSON이어야 합니다. 실제 order_id/user_id
등의 필드는 서버에 의해 채워지며 임의의 더미 값이 전달될 수 있습니다.
예시 요청
curl 'http://localhost:54545/api/v1/order/id'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=cad8439e-dcc4-475e-94fc-12b75f85bb20; max-age=300; path=/; secure; SameSite=Lax'
-X POST
--data-raw ' {
"order_id": 1,
"user_id": 3,
"currency": "USD",
"line_items": [
{
"sku": "prod-course-1"
},
{
"sku": "prod-course-3"
}
]
}'
예시 응답
{
"data": {
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 11000,
"line_items": [
{
"line_id": 1,
"order_id": 1,
"prd_id": 1,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"grand": 10000,
"enabled": true,
"sku": "prod-course-1"
},
{
"line_id": 2,
"order_id": 1,
"prd_id": 2,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"grand": 1000,
"enabled": true,
"sku": "prod-course-3"
}
]
},
"msg": "Order found",
"status": "success"
}
line_item
필드에 상품을 추가/삭제하여 기존 주문을 수정합니다. 주문을 수정하려면 사용자가 로그인해야 하며 주문이 활성 상태여야 합니다. 제품을 추가/삭제하려면 주문 생성 또는 주문 받기의 이전 응답을 사용하세요.
예시 요청
curl 'http://localhost:54545/api/v1/order/id'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=cad8439e-dcc4-475e-94fc-12b75f85bb20; max-age=300; path=/; secure; SameSite=Lax'
-X PUT
--data-raw ' {
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 11000,
"line_items": [
{
"line_id": 2,
"order_id": 1,
"prd_id": 2,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"grand": 1000,
"enabled": true,
"sku": "prod-course-3"
}
]
}'
예시 응답
{
"data": {
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 1000,
"line_items": [
{
"line_id": 2,
"order_id": 1,
"prd_id": 2,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"grand": 1000,
"enabled": true,
"sku": "prod-course-3"
}
]
},
"msg": "Order found",
"status": "success"
}
주문 API 생성으로 생성된 주문 결제를 위한 스트라이프 URL을 가져옵니다. 주문 생성/주문 수정/주문 가져오기 API의 응답을 사용하여 요청을 보냅니다. 이 요청의 응답을 수정하지 마십시오. 실패하게 됩니다.
예시 요청
curl 'http://localhost:54545/api/v1/order/checkout'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=2f1be070-7256-4e84-a4ef-c14754cabcdb; max-age=300; path=/; secure; SameSite=Lax'
-X POST
--data-raw ' {
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 11000,
"line_items": [
{
"line_id": 2,
"order_id": 1,
"prd_id": 2,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"grand": 1000,
"enabled": true,
"sku": "prod-course-3"
}
]
}'
예시 응답
{
"data": {
"url": "https://checkout.stripe.com/pay/cs_test_a17D2l74NsKMv29YJ1c5rSBPx7BGSsNAsObGAsOanEJqyFNXKEYDLji4BZ#fidkdWxOYHwnPyd1blpxYHZxWjA0TlVKPHNMaW9vYEd1YmhdUWQ3UUJqSEpMYTMza11ObGAyXDFPcXA8bz1yY1VicVZVdDN8c1NkaUZEazxIQWdjM04wdz1DTmF3PXxHaVE9bTVuZz1pUWw3NTUybHZLZldgaicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl"
},
"msg": "Order found",
"status": "success"
}
주문 번호로 주문 세부 정보 가져오기
예시 요청
curl 'http://localhost:54545/api/v1/order/id/cafjktbn0gpp5hq3dt4g'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=fe9b9fff-c5c0-4745-becf-ecb0e5abca81; max-age=300; path=/; secure; SameSite=Lax'
예시 응답
{
"data": {
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 1000,
"line_items": [
{
"line_id": 2,
"order_id": 1,
"prd_id": 2,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"grand": 1000,
"enabled": true
}
]
},
"msg": "Order found",
"status": "success"
}
사용자별로 모든 주문을 받습니다. 쿼리 매개변수 기본값은 각각 10과 0이므로 제한과 오프셋을 사용합니다.
예시 요청
curl 'http://localhost:54545/api/v1/order/id/list?limit=1&offset=0'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=fe9b9fff-c5c0-4745-becf-ecb0e5abca81; max-age=300; path=/; secure; SameSite=Lax'
예시 응답
{
"data": [
{
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"grand_total": 1000
}
],
"msg": "Order found",
"status": "success"
}
사용자 비밀번호를 변경하세요. 이 요청을 하려면 사용자가 로그인해야 합니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/changepwd'
-H 'Content-Type: application/x-www-form-urlencoded'
-H 'Cookie: session_id=fe9b9fff-c5c0-4745-becf-ecb0e5abca81; max-age=300; path=/; secure; SameSite=Lax'
-X POST
--data-raw 'oldpassword=cafjjjbn0gpp5hq3dt40&password=test123'
예시 응답
{
"data": null,
"msg": "password change successful",
"status": "success"
}
매장에서 생성된 모든 주문을 가져옵니다. 쿼리 매개변수 기본값은 각각 10과 0이므로 제한과 오프셋을 사용합니다. 관리자만 사용할 수 있습니다. 모든 주문 받기
예시 요청
curl 'http://localhost:54545/api/v1/order/list?limit=1&offset=0'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=e4ecd3a4-b8be-493e-a33d-518ab11c65e8; max-age=300; path=/; secure; SameSite=Lax'
예시 응답
{
"data": [
{
"order_id": 1,
"user_id": 3,
"created_at": "2022-06-07 11:45:57.601996759 +0000 UTC",
"modified_at": "2022-06-07 11:48:05.425488765 +0000 UTC",
"status": "active",
"currency": "USD",
"order_number": "cafjktbn0gpp5hq3dt4g",
"price_total": 1000,
"discount_total": 0,
"sub_total": 1000,
"taxes_total": 0,
"grand_total": 1000,
"refunds_total": 0,
"created_channel": "",
"payment_provider": ""
}
],
"msg": "Order found",
"status": "success"
}
웹사이트에 등록된 모든 사용자를 확보하세요. 쿼리 매개변수 기본값은 각각 10과 0이므로 제한과 오프셋을 사용합니다. 관리자만 사용할 수 있습니다.
예시 요청
curl 'http://localhost:54545/api/v1/user/list?limit=1&offset=0'
-H 'Content-Type: application/json; charset=utf-8'
-H 'Cookie: session_id=e4ecd3a4-b8be-493e-a33d-518ab11c65e8; max-age=300; path=/; secure; SameSite=Lax'
예시 응답
{
"data": [
{
"user_id": 1,
"email": "[email protected]",
"created_at": "2022-06-07 10:53:00.480128762 +0000 UTC",
"username": "",
"last_password_set": "2022-06-07 10:53:00.480128762 +0000 UTC",
"last_login": "2022-06-07 10:53:00.480128762 +0000 UTC",
"verified": 0,
"reset": 0,
"user_role": "admin"
},
{
"user_id": 2,
"email": "[email protected]",
"created_at": "2022-06-07 10:53:00.532691788 +0000 UTC",
"username": "",
"last_password_set": "2022-06-07 10:53:00.532691788 +0000 UTC",
"last_login": "2022-06-07 10:53:00.532691788 +0000 UTC",
"verified": 0,
"reset": 0,
"user_role": "guest"
},
{
"user_id": 3,
"email": "[email protected]",
"created_at": "2022-06-07 11:13:06.947313364 +0000 UTC",
"username": "",
"last_password_set": "2022-06-07 11:13:06.947313364 +0000 UTC",
"last_login": "2022-06-07 11:13:06.947313364 +0000 UTC",
"verified": 2,
"reset": 1,
"user_role": "user"
}
],
"msg": "Order found",
"status": "success"
}
아니요. 바이너리만 출시되며 사이트는 제품에 대한 토론에 사용됩니다.
알파 단계의 기능은 완전하지만 버그가 있을 수 있습니다.
강좌를 개설해야 한다는 필요성 때문에 만들어졌습니다.
지금은 구독이 지원되지 않기 때문에 일회성 디지털 제품에만 적용됩니다. 또한 자체 SaaS를 연결할 수 있는 경로 전달 기능도 없습니다. 그러나 관심이 충분하다면 이러한 변경 사항을 추가할 수 있습니다. 현재로서는 이러한 기능을 갖고 싶다면 로드맵에 없습니다.
강좌 호스팅 및 관련 블로그에 사용할 수 있습니다. 뉴스레터가 포함된 블로그. 프리미엄 콘텐츠가 포함된 블로그. 스타트업 랜딩페이지 및 관련 블로그입니다. 테마 등 판매
Linux와 Macos는 기본적으로 지원됩니다. Windows 사용자는 WSL을 사용할 수 있지만 테스트되지 않았습니다.
이슈를 생성하고 기능으로 태그 지정
아직 결정되지 않았으며 현재 무료로 사용할 수 있습니다. 유료 제품이 있는 경우 별도의 채널을 사용합니다. 따라서 github 릴리스에서 다운로드하는 경우 영원히 무료입니다. 우리가 결정하는 데 도움을 주고, 토론 게시판에서 얼마를 지불할지 알려주세요.