Compare commits

...

53 Commits

Author SHA1 Message Date
Andras Bacsai
a116028e1b Merge pull request #137 from coollabsio/next
v2.0.12
2022-02-15 22:03:10 +01:00
Andras Bacsai
e606a02b29 Update packages 2022-02-15 21:49:14 +01:00
Andras Bacsai
531c712ea5 fix: Some nasty bug
fix: Automatic reconfiguration of all services and service proxies
2022-02-15 21:44:36 +01:00
Andras Bacsai
3ae7624361 fix: Cleanup images 2022-02-15 20:37:00 +01:00
Andras Bacsai
fed83462fa remove unncesarry logs 2022-02-15 20:34:40 +01:00
Andras Bacsai
58c9f937c5 fix: Cleanup every 10 mins 2022-02-15 19:14:23 +01:00
Andras Bacsai
5d14b9209d fix: Coolify image cleanup 2022-02-15 19:13:50 +01:00
Andras Bacsai
305a95fa74 fix: TransactionIds 2022-02-15 18:47:20 +01:00
Andras Bacsai
b29c1e702a fix: isDomainConfigured 2022-02-15 18:04:58 +01:00
Andras Bacsai
b04d75ab08 dx: only allow cleanup in production 2022-02-15 17:46:37 +01:00
Andras Bacsai
25abfaadb9 chore: version++ 2022-02-15 17:45:58 +01:00
Andras Bacsai
1df81b8698 fix: Unnecessary proxy restart
feat: Restart proxy
2022-02-15 17:45:20 +01:00
Andras Bacsai
4487846fd7 feat: Force restart coolify proxy
fix: Cannot configure coolify proxy
2022-02-15 15:55:55 +01:00
Andras Bacsai
86918f5160 Merge pull request #134 from coollabsio/next
fix: Error with follow logs
2022-02-15 10:59:58 +01:00
Andras Bacsai
bc723b3f15 fix: Error with follow logs 2022-02-15 10:57:58 +01:00
Andras Bacsai
1881e646d4 Merge pull request #132 from coollabsio/next
v2.0.11
2022-02-15 10:51:25 +01:00
Andras Bacsai
aa98808a1a fix: Typo 2022-02-15 10:46:44 +01:00
Andras Bacsai
f9a2232703 fix: Small fixes 2022-02-15 10:42:26 +01:00
Andras Bacsai
19d6be8663 fix: Load more button 2022-02-15 10:35:22 +01:00
Andras Bacsai
0eb7c890ad fix: GitHub sync PR's 2022-02-15 10:25:23 +01:00
Andras Bacsai
7bfa68aa58 chore: version++ 2022-02-15 09:40:04 +01:00
Andras Bacsai
857a38050e fix: Window error in SSR 2022-02-15 09:39:45 +01:00
Andras Bacsai
c5b7f92caf feat: Follow logs 2022-02-15 09:38:16 +01:00
Andras Bacsai
df31ffd7fb Merge pull request #127 from SaraVieira/logs-improvements
UX improvements for the log page
2022-02-15 09:02:43 +01:00
Andras Bacsai
0df0322d36 Merge pull request #129 from coollabsio/next
v2.0.10
2022-02-15 08:52:45 +01:00
Andras Bacsai
260552322d chore: Version++ 2022-02-15 08:50:17 +01:00
Andras Bacsai
88ef6496a2 fix: Coolify proxy start 2022-02-15 08:50:02 +01:00
Andras Bacsai
bdf123bf7b fix: Stopping service without proxy 2022-02-15 08:38:16 +01:00
Andras Bacsai
8fc3760eef fix: Error handling 2022-02-14 16:52:00 +01:00
Sara Vieira
5656f6f709 add env example back 2022-02-14 16:01:08 +01:00
Andras Bacsai
53e7e8b77e version bump 2022-02-14 15:59:00 +01:00
Andras Bacsai
b990915b7a fix: Typo 2022-02-14 15:58:44 +01:00
Sara Vieira
15b7822ffd put db in the right place 2022-02-14 15:58:42 +01:00
Sara Vieira
cfa28419cb add yarn lock to gitignore 2022-02-14 15:56:28 +01:00
Sara Vieira
30ef0d2a3a some log improvements 2022-02-14 15:55:19 +01:00
Andras Bacsai
755f99200a Create README.md 2022-02-14 11:32:19 +01:00
Andras Bacsai
7af79ed3a2 Update README.md 2022-02-14 11:29:56 +01:00
Andras Bacsai
2971e14269 Merge pull request #123 from coollabsio/next
v2.0.8
2022-02-14 10:09:07 +01:00
Andras Bacsai
01954aaf30 Merge pull request #122 from habibyuri/patch-1
Allow Docker Apache write permissions
2022-02-14 10:03:31 +01:00
Andras Bacsai
da018a8f2a fix: Branch used does not throw error 2022-02-14 09:57:17 +01:00
Andras Bacsai
77400bbbb0 fix: Truncate git clone errors 2022-02-14 09:48:46 +01:00
Andras Bacsai
3c3333d3df fix: Validate secrets 2022-02-14 09:47:09 +01:00
Andras Bacsai
4963bd4144 - Bump version
- Fix type
2022-02-14 09:28:56 +01:00
Andras Bacsai
b4a418dded - Rename error handler.
- Truncate errors.
- Better error tags, release version etc.
2022-02-14 09:28:37 +01:00
Yuri Habib
a724b0daee Allow Docker Apache write permissions
I had a permission problem using PHP scripts, 
Running ` chown -R www-data /var/www/html ` after SSHing into the docker container helped fixing the problem.
2022-02-13 14:58:13 -08:00
Andras Bacsai
88aa620cb4 Merge pull request #121 from coollabsio/next
v2.0.7
2022-02-13 23:45:49 +01:00
Andras Bacsai
70d3448110 fix: New secret should have default values 2022-02-13 23:31:52 +01:00
Andras Bacsai
09a1a406a6 Bump version 2022-02-13 23:19:08 +01:00
Andras Bacsai
40939d0b7f fix: Build secrets should be visible in runtime 2022-02-13 23:17:50 +01:00
Andras Bacsai
aec1d184c8 feat: www <-> non-www redirection 2022-02-13 22:56:37 +01:00
Andras Bacsai
69d3cb5dd8 feat: www <-> non-www redirection for apps 2022-02-13 15:04:00 +01:00
Andras Bacsai
3deff162bb code cleanup 2022-02-13 13:46:51 +01:00
Andras Bacsai
4ed54568d3 fix: package.json 2022-02-12 15:34:55 +01:00
125 changed files with 1020 additions and 801 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@ node_modules
/build
/.svelte-kit
/package
/yarn.lock
.env
.env.prod

View File

@@ -71,9 +71,7 @@ You can use the official ones or your self hosted version!
## Roadmap
[See the Roadmap here](https://github.com/coollabsio/coolify/projects/1)
(Will be updated soon!)
[See the Roadmap here](https://github.com/orgs/coollabsio/projects/3/views/8)
## License

View File

@@ -1,7 +1,7 @@
{
"name": "coolify",
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
"version": "2.0.6",
"version": "2.0.12",
"license": "AGPL-3.0",
"scripts": {
"dev": "docker compose -f docker-compose-dev.yaml up -d && NODE_ENV=development svelte-kit dev --host 0.0.0.0",
@@ -17,7 +17,8 @@
"db:push": "prisma db push && prisma generate",
"db:seed": "prisma db seed",
"release:staging": "cross-var docker build -t coollabsio/coolify:$npm_package_version . && docker push coollabsio/coolify:$npm_package_version",
"release:coolify": "cross-var yarn prerelease && docker push coollabsio/coolify:$npm_package_version && docker image push coollabsio/coolify:$npm_package_version && docker push coollabsio/coolify:latest",
"release:pre": "cross-var docker build -t coollabsio/coolify:$npm_package_version -t coollabsio/coolify:latest .",
"release:coolify": "cross-var yarn release:pre && docker push coollabsio/coolify:$npm_package_version && docker push coollabsio/coolify:latest",
"release:haproxy": "docker build -f haproxy.Dockerfile -t coollabsio/coolify-haproxy-alpine:1.0.0 -t coollabsio/coolify-haproxy-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-alpine",
"release:haproxy:tcp": "docker build -f haproxy-tcp.Dockerfile -t coollabsio/coolify-haproxy-tcp-alpine:1.0.0 -t coollabsio/coolify-haproxy-tcp-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-tcp-alpine",
"release:haproxy:http": "docker build -f haproxy-http.Dockerfile -t coollabsio/coolify-haproxy-http-alpine:1.0.0 -t coollabsio/coolify-haproxy-http-alpine:latest . && docker image push --all-tags coollabsio/coolify-haproxy-http-alpine",
@@ -29,7 +30,7 @@
"@sveltejs/kit": "1.0.0-next.259",
"@types/bcrypt": "5.0.0",
"@types/js-cookie": "3.0.1",
"@types/node": "17.0.16",
"@types/node": "17.0.18",
"@types/node-forge": "1.0.0",
"@typescript-eslint/eslint-plugin": "4.31.1",
"@typescript-eslint/parser": "4.31.1",
@@ -40,16 +41,16 @@
"eslint-config-prettier": "8.3.0",
"eslint-plugin-svelte3": "3.2.1",
"husky": "7.0.4",
"lint-staged": "12.3.3",
"lint-staged": "12.3.4",
"postcss": "8.4.6",
"prettier": "2.5.1",
"prettier-plugin-svelte": "2.6.0",
"prettier-plugin-tailwindcss": "0.1.7",
"prisma": "3.9.1",
"prisma": "3.9.2",
"svelte": "3.46.4",
"svelte-check": "2.4.3",
"svelte-preprocess": "4.10.3",
"tailwindcss": "3.0.19",
"tailwindcss": "3.0.22",
"ts-node": "10.5.0",
"tslib": "2.3.1",
"typescript": "4.5.5"
@@ -57,10 +58,10 @@
"type": "module",
"dependencies": {
"@iarna/toml": "2.2.5",
"@prisma/client": "3.9.1",
"@sentry/node": "6.17.6",
"@prisma/client": "3.9.2",
"@sentry/node": "6.17.8",
"bcrypt": "5.0.1",
"bullmq": "1.69.0",
"bullmq": "1.72.0",
"compare-versions": "4.1.3",
"cookie": "0.4.2",
"cuid": "2.1.8",
@@ -74,7 +75,7 @@
"js-yaml": "4.1.0",
"jsonwebtoken": "8.5.1",
"node-forge": "1.2.1",
"svelte-kit-cookie-session": "2.0.3",
"svelte-kit-cookie-session": "2.0.5",
"unique-names-generator": "4.6.0"
},
"prisma": {

147
pnpm-lock.yaml generated
View File

@@ -2,21 +2,21 @@ lockfileVersion: 5.3
specifiers:
'@iarna/toml': 2.2.5
'@prisma/client': 3.9.1
'@sentry/node': 6.17.6
'@prisma/client': 3.9.2
'@sentry/node': 6.17.8
'@sveltejs/adapter-node': 1.0.0-next.67
'@sveltejs/adapter-static': 1.0.0-next.27
'@sveltejs/kit': 1.0.0-next.259
'@types/bcrypt': 5.0.0
'@types/js-cookie': 3.0.1
'@types/node': 17.0.16
'@types/node': 17.0.18
'@types/node-forge': 1.0.0
'@typescript-eslint/eslint-plugin': 4.31.1
'@typescript-eslint/parser': 4.31.1
'@zerodevx/svelte-toast': 0.6.3
autoprefixer: 10.4.2
bcrypt: 5.0.1
bullmq: 1.69.0
bullmq: 1.72.0
compare-versions: 4.1.3
cookie: 0.4.2
cross-var: 1.1.0
@@ -34,18 +34,18 @@ specifiers:
js-cookie: 3.0.1
js-yaml: 4.1.0
jsonwebtoken: 8.5.1
lint-staged: 12.3.3
lint-staged: 12.3.4
node-forge: 1.2.1
postcss: 8.4.6
prettier: 2.5.1
prettier-plugin-svelte: 2.6.0
prettier-plugin-tailwindcss: 0.1.7
prisma: 3.9.1
prisma: 3.9.2
svelte: 3.46.4
svelte-check: 2.4.3
svelte-kit-cookie-session: 2.0.3
svelte-kit-cookie-session: 2.0.5
svelte-preprocess: 4.10.3
tailwindcss: 3.0.19
tailwindcss: 3.0.22
ts-node: 10.5.0
tslib: 2.3.1
typescript: 4.5.5
@@ -53,10 +53,10 @@ specifiers:
dependencies:
'@iarna/toml': 2.2.5
'@prisma/client': 3.9.1_prisma@3.9.1
'@sentry/node': 6.17.6
'@prisma/client': 3.9.2_prisma@3.9.2
'@sentry/node': 6.17.8
bcrypt: 5.0.1
bullmq: 1.69.0
bullmq: 1.72.0
compare-versions: 4.1.3
cookie: 0.4.2
cuid: 2.1.8
@@ -70,7 +70,7 @@ dependencies:
js-yaml: 4.1.0
jsonwebtoken: 8.5.1
node-forge: 1.2.1
svelte-kit-cookie-session: 2.0.3
svelte-kit-cookie-session: 2.0.5
unique-names-generator: 4.6.0
devDependencies:
@@ -79,7 +79,7 @@ devDependencies:
'@sveltejs/kit': 1.0.0-next.259_svelte@3.46.4
'@types/bcrypt': 5.0.0
'@types/js-cookie': 3.0.1
'@types/node': 17.0.16
'@types/node': 17.0.18
'@types/node-forge': 1.0.0
'@typescript-eslint/eslint-plugin': 4.31.1_5d7752337e5ea49772097d8af1823bf9
'@typescript-eslint/parser': 4.31.1_eslint@7.32.0+typescript@4.5.5
@@ -90,17 +90,17 @@ devDependencies:
eslint-config-prettier: 8.3.0_eslint@7.32.0
eslint-plugin-svelte3: 3.2.1_eslint@7.32.0+svelte@3.46.4
husky: 7.0.4
lint-staged: 12.3.3
lint-staged: 12.3.4
postcss: 8.4.6
prettier: 2.5.1
prettier-plugin-svelte: 2.6.0_prettier@2.5.1+svelte@3.46.4
prettier-plugin-tailwindcss: 0.1.7_prettier@2.5.1
prisma: 3.9.1
prisma: 3.9.2
svelte: 3.46.4
svelte-check: 2.4.3_postcss@8.4.6+svelte@3.46.4
svelte-preprocess: 4.10.3_88b359da5cac6d8f6ee1bbb7080a3fa9
tailwindcss: 3.0.19_27d966e3a2f4b84fbc8a2f9653dbb362
ts-node: 10.5.0_99ae9436e134a034c8d45fdd98ebbf22
tailwindcss: 3.0.22_c940fbabf228b85b1c73d314b43e31f1
ts-node: 10.5.0_f3bd4037939c2ed2942ba074291f8ef2
tslib: 2.3.1
typescript: 4.5.5
@@ -250,10 +250,10 @@ packages:
fastq: 1.13.0
dev: true
/@prisma/client/3.9.1_prisma@3.9.1:
/@prisma/client/3.9.2_prisma@3.9.2:
resolution:
{
integrity: sha512-aLwfXKLvL+loQ0IuPPCXkcq8cXBg1IeoHHa5lqQu3dJHdj45wnislA/Ny4UxRQjD5FXqrfAb8sWtF+jhdmjFTg==
integrity: sha512-VlEIYVMyfFZHbVBOlunPl47gmP/Z0zzPjPj8I7uKEIaABqrUy50ru3XS0aZd8GFvevVwt7p91xxkUjNjrWhKAQ==
}
engines: { node: '>=12.6' }
requiresBuild: true
@@ -264,7 +264,7 @@ packages:
optional: true
dependencies:
'@prisma/engines-version': 3.9.0-58.bcc2ff906db47790ee902e7bbc76d7ffb1893009
prisma: 3.9.1
prisma: 3.9.2
dev: false
/@prisma/engines-version/3.9.0-58.bcc2ff906db47790ee902e7bbc76d7ffb1893009:
@@ -293,56 +293,56 @@ packages:
picomatch: 2.3.0
dev: true
/@sentry/core/6.17.6:
/@sentry/core/6.17.8:
resolution:
{
integrity: sha512-wSNsQSqsW8vQ2HEvUEXYOJnzTyVDSWbyH4RHrWV1pQM8zqGx/qfz0sKFM5XFnE9ZeaXKL8LXV3v5i73v+z8lew==
integrity: sha512-4WTjgQom75Rvgn6XYy6e7vMIbWlj8utau1wWvr7kjqFKuuuuycRvPgVzAdVr4B3WDHHCInAZpUchsOLs2qwIEA==
}
engines: { node: '>=6' }
dependencies:
'@sentry/hub': 6.17.6
'@sentry/minimal': 6.17.6
'@sentry/types': 6.17.6
'@sentry/utils': 6.17.6
'@sentry/hub': 6.17.8
'@sentry/minimal': 6.17.8
'@sentry/types': 6.17.8
'@sentry/utils': 6.17.8
tslib: 1.14.1
dev: false
/@sentry/hub/6.17.6:
/@sentry/hub/6.17.8:
resolution:
{
integrity: sha512-Ps9nk+DoFia8jhZ1lucdRE0vDx8hqXOsKXJE8a3hK/Ndki0J9jedYqBeLqSgiFG4qRjXpNFcD6TEM6tnQrv5lw==
integrity: sha512-GW0XYpkoQu/kSJaTLfsF4extHDOBPNRnT0qKr/YO20Z5wGxYp8LsdnAuU3njcFHcAV2F/QDTj2BPq1U385/4+A==
}
engines: { node: '>=6' }
dependencies:
'@sentry/types': 6.17.6
'@sentry/utils': 6.17.6
'@sentry/types': 6.17.8
'@sentry/utils': 6.17.8
tslib: 1.14.1
dev: false
/@sentry/minimal/6.17.6:
/@sentry/minimal/6.17.8:
resolution:
{
integrity: sha512-PLGf8WlhtdHuY6ofwYR3nyClr/TYHHAW6i0r62OZCOXTqnFPJorZpAz3VCCP2jMJmbgVbo03wN+u/xAA/zwObA==
integrity: sha512-VJXFZBO/O8SViK0fdzodxpNr+pbpgczNgLpz/MNuSooV6EBesgCMVjXtxDUp1Ie1odc0GUprN/ZMLYBmYdIrKQ==
}
engines: { node: '>=6' }
dependencies:
'@sentry/hub': 6.17.6
'@sentry/types': 6.17.6
'@sentry/hub': 6.17.8
'@sentry/types': 6.17.8
tslib: 1.14.1
dev: false
/@sentry/node/6.17.6:
/@sentry/node/6.17.8:
resolution:
{
integrity: sha512-T1s0yPbGvYpoh9pJgLvpy7s+jVwCyf0ieEoN9rSbnPwbi2vm6MfoV5wtGrE0cBHTPgnyOMv+zq4Q3ww6dfr7Pw==
integrity: sha512-b3zg1XjKtxp7o821ENORO1CCzMM4QzKP01rzztMwyMcj28dmUq36QXoQAnwdKn7jEYkJdLnMeniIBR6U6NUJrQ==
}
engines: { node: '>=6' }
dependencies:
'@sentry/core': 6.17.6
'@sentry/hub': 6.17.6
'@sentry/tracing': 6.17.6
'@sentry/types': 6.17.6
'@sentry/utils': 6.17.6
'@sentry/core': 6.17.8
'@sentry/hub': 6.17.8
'@sentry/tracing': 6.17.8
'@sentry/types': 6.17.8
'@sentry/utils': 6.17.8
cookie: 0.4.2
https-proxy-agent: 5.0.0
lru_map: 0.3.3
@@ -351,36 +351,36 @@ packages:
- supports-color
dev: false
/@sentry/tracing/6.17.6:
/@sentry/tracing/6.17.8:
resolution:
{
integrity: sha512-+h5ov+zEm5WH9+vmFfdT4EIqBOW7Tggzh0BDz8QRStRc2JbvEiSZDs+HlsycBwWMQi/ucJs93FPtNnWjW+xvBw==
integrity: sha512-WJ3W8O6iPI3w7MrzTnYcw3s5PGBNFqT4b9oBCl5Ndjexs8DsGlQOxjrsipo36z6TpnRHpAE4FEbOETb2R8JRJQ==
}
engines: { node: '>=6' }
dependencies:
'@sentry/hub': 6.17.6
'@sentry/minimal': 6.17.6
'@sentry/types': 6.17.6
'@sentry/utils': 6.17.6
'@sentry/hub': 6.17.8
'@sentry/minimal': 6.17.8
'@sentry/types': 6.17.8
'@sentry/utils': 6.17.8
tslib: 1.14.1
dev: false
/@sentry/types/6.17.6:
/@sentry/types/6.17.8:
resolution:
{
integrity: sha512-peGM873lDJtHd/jwW9Egr/hhxLuF0bcPIf2kMZlvEvW/G5GCbuaCR4ArQJlh7vQyma+NLn/XdojpJkC0TomKrw==
integrity: sha512-0i0f+dpvV62Pm5QMVBHNfEsTGIXoXRGQbeN2LGL4XbhzrzUmIrBPzrnZHv9c/JYtSJnI6A0B9OG7Bdlh3aku+Q==
}
engines: { node: '>=6' }
dev: false
/@sentry/utils/6.17.6:
/@sentry/utils/6.17.8:
resolution:
{
integrity: sha512-RI797N8Ax5yuKUftVX6dc0XmXqo5CN7XqJYPFzYC8udutQ4L8ZYadtUcqNsdz1ZQxl+rp0XK9Q6wjoWmsI2RXA==
integrity: sha512-cAOM53A5FHv95hpDuXKJU8rI4B1XdZ6qe3Yo+/nDS9QDpOgzvyjcItgXPvKW1wUjdHCcnwu7VBfBxB7teYOW9g==
}
engines: { node: '>=6' }
dependencies:
'@sentry/types': 6.17.6
'@sentry/types': 6.17.8
tslib: 1.14.1
dev: false
@@ -502,7 +502,7 @@ packages:
integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==
}
dependencies:
'@types/node': 17.0.16
'@types/node': 17.0.18
dev: true
/@types/cacheable-request/6.0.2:
@@ -513,7 +513,7 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.3
'@types/node': 17.0.16
'@types/node': 17.0.18
'@types/responselike': 1.0.0
dev: false
@@ -544,7 +544,7 @@ packages:
integrity: sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==
}
dependencies:
'@types/node': 17.0.16
'@types/node': 17.0.18
dev: false
/@types/node-forge/1.0.0:
@@ -553,13 +553,13 @@ packages:
integrity: sha512-h0bgwPKq5u99T9Gor4qtV1lCZ41xNkai0pie1n/a2mh2/4+jENWOlo7AJ4YKxTZAnSZ8FRurUpdIN7ohaPPuHA==
}
dependencies:
'@types/node': 17.0.16
'@types/node': 17.0.18
dev: true
/@types/node/17.0.16:
/@types/node/17.0.18:
resolution:
{
integrity: sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA==
integrity: sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==
}
/@types/parse-json/4.0.0:
@@ -582,7 +582,7 @@ packages:
integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
}
dependencies:
'@types/node': 17.0.16
'@types/node': 17.0.18
dev: false
/@types/sass/1.16.1:
@@ -591,7 +591,7 @@ packages:
integrity: sha512-iZUcRrGuz/Tbg3loODpW7vrQJkUtpY2fFSf4ELqqkApcS2TkZ1msk7ie8iZPB86lDOP8QOTTmuvWjc5S0R9OjQ==
}
dependencies:
'@types/node': 17.0.16
'@types/node': 17.0.18
dev: true
/@typescript-eslint/eslint-plugin/4.31.1_5d7752337e5ea49772097d8af1823bf9:
@@ -1746,10 +1746,10 @@ packages:
ieee754: 1.2.1
dev: false
/bullmq/1.69.0:
/bullmq/1.72.0:
resolution:
{
integrity: sha512-1aIO7bN0HQeADWoXa+I72GgofvoBFRs/kcoveB3KN8ytKv7QJbGhtks0pYNhHn/P9H3OWHWDccpNEfnv3VGfcw==
integrity: sha512-Q0pk6GphHyYsacpjZZFhjp/+TY+2g2FDsJS3qwIyskQL4j7vZaa1iYX3gKDEBn4C5eZMP1EOl9GWkm2bhdB0Wg==
}
dependencies:
cron-parser: 2.18.0
@@ -3718,10 +3718,10 @@ packages:
resolution: { integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= }
dev: true
/lint-staged/12.3.3:
/lint-staged/12.3.4:
resolution:
{
integrity: sha512-OqcLsqcPOqzvsfkxjeBpZylgJ3SRG1RYqc9LxC6tkt6tNsq1bNVkAixBwX09f6CobcHswzqVOCBpFR1Fck0+ag==
integrity: sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==
}
engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
hasBin: true
@@ -4397,7 +4397,7 @@ packages:
dependencies:
import-cwd: 3.0.0
lilconfig: 2.0.4
ts-node: 10.5.0_99ae9436e134a034c8d45fdd98ebbf22
ts-node: 10.5.0_f3bd4037939c2ed2942ba074291f8ef2
yaml: 1.10.2
dev: true
@@ -4486,10 +4486,10 @@ packages:
hasBin: true
dev: true
/prisma/3.9.1:
/prisma/3.9.2:
resolution:
{
integrity: sha512-IGcJAu5LzlFv+i+NNhOEh1J1xVVttsVdRBxmrMN7eIH+7mRN6L89Hz1npUAiz4jOpNlHC7n9QwaOYZGxTqlwQw==
integrity: sha512-i9eK6cexV74OgeWaH3+e6S07kvC9jEZTl6BqtBH398nlCU0tck7mE9dicY6YQd+euvMjjCtY89q4NgmaPnUsSg==
}
engines: { node: '>=12.6' }
hasBin: true
@@ -5203,10 +5203,10 @@ packages:
svelte: 3.46.4
dev: true
/svelte-kit-cookie-session/2.0.3:
/svelte-kit-cookie-session/2.0.5:
resolution:
{
integrity: sha512-jOBUpvrkt/fI5zaqWsWHDDIGnfuPQt3/PC1FDJpEV/E/hA8DvGO52esFny1HvUAP1tkVZ5FU3k6Yd3HyQH5oUQ==
integrity: sha512-IX1IXtn42UTz/isem1LqH0SAZdCx6Z6Iu2V4Q83V2EScFbXZWfeFY08Azl8ZrPKdIDhSNHBLAAumRjA6TBxCvQ==
}
dev: false
@@ -5288,16 +5288,15 @@ packages:
strip-ansi: 6.0.1
dev: true
/tailwindcss/3.0.19_27d966e3a2f4b84fbc8a2f9653dbb362:
/tailwindcss/3.0.22_c940fbabf228b85b1c73d314b43e31f1:
resolution:
{
integrity: sha512-rjsdfz/qZya5xQ0OVynEMETgWq1CacmftgMYeXXh6bRM5vxsNwRSbMJsCCIjq/w67om9VP/AFMolOwiE+5VKig==
integrity: sha512-F8lt74RlNZirnkaSk310+vGQta7c0/hgx7/bqxruM4wS9lp8oqV93lzavajC3VT0Lp4UUtUVIt8ifKcmGzkr0A==
}
engines: { node: '>=12.13.0' }
hasBin: true
peerDependencies:
autoprefixer: ^10.0.2
postcss: ^8.0.9
dependencies:
arg: 5.0.1
autoprefixer: 10.4.2_postcss@8.4.6
@@ -5408,7 +5407,7 @@ packages:
engines: { node: '>=0.10.0' }
dev: true
/ts-node/10.5.0_99ae9436e134a034c8d45fdd98ebbf22:
/ts-node/10.5.0_f3bd4037939c2ed2942ba074291f8ef2:
resolution:
{
integrity: sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==
@@ -5430,7 +5429,7 @@ packages:
'@tsconfig/node12': 1.0.9
'@tsconfig/node14': 1.0.1
'@tsconfig/node16': 1.0.2
'@types/node': 17.0.16
'@types/node': 17.0.18
acorn: 8.5.0
acorn-walk: 8.2.0
arg: 4.1.3

View File

@@ -74,26 +74,12 @@ export async function makeLabelForStandaloneDatabase({ id, image, volume }) {
];
}
export async function makeLabelForPlausibleAnalytics({ id, images, volume }) {
const service = await db.prisma.service.findFirst({
where: { id },
include: { plausibleAnalytics: true }
});
delete service.destinationDockerId;
delete service.createdAt;
delete service.updatedAt;
export function makeLabelForServices(type) {
return [
'coolify.managed=true',
`coolify.version=${version}`,
`coolify.type=service-plausibleanalytics`,
`coolify.configuration=${base64Encode(
JSON.stringify({
version,
images,
volume,
...service
})
)}`
`coolify.type=service`,
`coolify.service.type=${type}`
];
}

View File

@@ -11,6 +11,7 @@ const createDockerfile = async (data, image): Promise<void> => {
Dockerfile.push(`COPY ./${baseDirectory || ''} /var/www/html`);
Dockerfile.push(`EXPOSE 80`);
Dockerfile.push('CMD ["apache2-foreground"]');
Dockerfile.push('RUN chown -R www-data /var/www/html');
await fs.writeFile(`${workdir}/Dockerfile`, Dockerfile.join('\n'));
};

View File

@@ -8,16 +8,26 @@ import * as db from '$lib/database';
import { buildLogQueue } from './queues';
import { version as currentVersion } from '../../package.json';
import { dockerInstance } from './docker';
import dayjs from 'dayjs';
import Cookie from 'cookie';
import os from 'os';
try {
if (!dev) {
Sentry.init({
dsn: process.env['COOLIFY_SENTRY_DSN'],
tracesSampleRate: 0,
environment: 'production'
environment: 'production',
debug: true,
release: currentVersion,
initialScope: {
tags: {
appId: process.env['COOLIFY_APP_ID'],
'os.arch': os.arch(),
'os.platform': os.platform(),
'os.release': os.release()
}
}
});
}
} catch (err) {
@@ -67,7 +77,6 @@ export const getTeam = (event) => {
};
export const getUserDetails = async (event, isAdminRequired = true) => {
// try {
const teamId = getTeam(event);
const userId = event.locals.session.data.uid || null;
const { permission = 'read' } = await db.prisma.permission.findFirst({
@@ -91,18 +100,6 @@ export const getUserDetails = async (event, isAdminRequired = true) => {
}
return payload;
// } catch (err) {
// console.log(err);
// return {
// teamId: null,
// userId: null,
// permission: 'read',
// status: 401,
// body: {
// message: 'You do not have permission to do this. \nAsk an admin to modify your permissions.'
// }
// };
// }
};
export function getEngine(engine) {

View File

@@ -20,9 +20,6 @@
function showActions(value) {
actionsShow = value;
// if (value === false) {
// showPassword = false;
// }
}
function copyToClipboard() {
if (isHttps && navigator.clipboard) {

View File

@@ -6,7 +6,6 @@
export let description;
export let isPadding = true;
export let disabled = false;
// export let disabledReason = '';
</script>
<li class="flex items-center py-4">
@@ -14,11 +13,6 @@
<p class="text-xs font-bold text-stone-100 md:text-base">{title}</p>
<Explainer text={description} />
</div>
<!-- {#if disabled}
<div class="flex" class:px-4={isPadding} class:pr-32={!isPadding}>
<p class="text-xs font-bold text-stone-400">{disabledReason}</p>
</div>
{:else} -->
<div
type="button"
on:click

View File

@@ -1,5 +1,5 @@
import { decrypt, encrypt } from '$lib/crypto';
import { removeProxyConfiguration } from '$lib/haproxy';
import { removeProxyConfiguration, removeWwwRedirection } from '$lib/haproxy';
import { asyncExecShell, getEngine } from '$lib/common';
import { getDomain, removeDestinationDocker } from '$lib/common';
@@ -59,10 +59,14 @@ export async function removeApplication({ id, teamId }) {
const id = containerObj.ID;
const preview = containerObj.Image.split('-')[1];
await removeDestinationDocker({ id, engine: destinationDocker.engine });
if (preview) {
await removeProxyConfiguration({ domain: `${preview}.${domain}` });
} else {
await removeProxyConfiguration({ domain });
try {
if (preview) {
await removeProxyConfiguration({ domain: `${preview}.${domain}` });
} else {
await removeProxyConfiguration({ domain });
}
} catch (error) {
console.log(error);
}
}
}
@@ -113,6 +117,13 @@ export async function getApplicationWebhook({ projectId, branch }) {
throw { status: 404, body: { message: e.message } };
}
}
export async function getApplicationById({ id }) {
const body = await prisma.application.findFirst({
where: { id }
});
return { ...body };
}
export async function getApplication({ id, teamId }) {
let body = await prisma.application.findFirst({
where: { id, teams: { some: { id: teamId } } },

View File

@@ -22,15 +22,15 @@ export async function isSecretExists({ id, name }) {
export async function isDomainConfigured({ id, fqdn }) {
const domain = getDomain(fqdn);
const foundApp = await prisma.application.findFirst({
where: { fqdn: { endsWith: domain }, id: { not: id } },
where: { fqdn: { endsWith: `//${domain}` }, id: { not: id } },
select: { fqdn: true }
});
const foundService = await prisma.service.findFirst({
where: { fqdn: { endsWith: domain }, id: { not: id } },
where: { fqdn: { endsWith: `//${domain}` }, id: { not: id } },
select: { fqdn: true }
});
const coolifyFqdn = await prisma.setting.findFirst({
where: { fqdn: { endsWith: domain }, id: { not: id } },
where: { fqdn: { endsWith: `//${domain}` }, id: { not: id } },
select: { fqdn: true }
});
if (foundApp || foundService || coolifyFqdn) return true;

View File

@@ -36,23 +36,36 @@ if (dev) {
}
export const prisma = new PrismaClient(prismaOptions);
export function PrismaErrorHandler(e) {
export function ErrorHandler(e) {
if (e! instanceof Error) {
e = new Error(e.toString());
}
sentry.captureException(e);
let truncatedError = e;
if (e.message?.includes('docker run')) {
let truncatedArray = [];
truncatedArray = truncatedError.message.split('-').filter((line) => {
if (!line.startsWith('e ')) {
return line;
}
});
truncatedError.message = truncatedArray.join('-');
}
if (e.message?.includes('git clone')) {
truncatedError.message = 'git clone failed';
}
sentry.captureException(truncatedError);
const payload = {
status: e.status || 500,
status: truncatedError.status || 500,
body: {
message: 'Ooops, something is not okay, are you okay?',
error: e.error || e.message
error: truncatedError.error || truncatedError.message
}
};
if (e.name === 'NotFoundError') {
if (truncatedError?.name === 'NotFoundError') {
payload.status = 404;
}
if (e instanceof P.PrismaClientKnownRequestError) {
if (e.code === 'P2002') {
if (truncatedError instanceof P.PrismaClientKnownRequestError) {
if (truncatedError?.code === 'P2002') {
payload.body.message = 'Already exists. Choose another name.';
}
}
@@ -101,27 +114,55 @@ export const supportedServiceTypesAndVersions = [
name: 'plausibleanalytics',
fancyName: 'Plausible Analytics',
baseImage: 'plausible/analytics',
versions: ['latest']
versions: ['latest'],
ports: {
main: 8000
}
},
{
name: 'nocodb',
fancyName: 'NocoDB',
baseImage: 'nocodb/nocodb',
versions: ['latest'],
ports: {
main: 8080
}
},
{
name: 'minio',
fancyName: 'MinIO',
baseImage: 'minio/minio',
versions: ['latest'],
ports: {
main: 9001
}
},
{ name: 'nocodb', fancyName: 'NocoDB', baseImage: 'nocodb/nocodb', versions: ['latest'] },
{ name: 'minio', fancyName: 'MinIO', baseImage: 'minio/minio', versions: ['latest'] },
{
name: 'vscodeserver',
fancyName: 'VSCode Server',
baseImage: 'codercom/code-server',
versions: ['latest']
versions: ['latest'],
ports: {
main: 8080
}
},
{
name: 'wordpress',
fancyName: 'Wordpress',
baseImage: 'wordpress',
versions: ['latest', 'php8.1', 'php8.0', 'php7.4', 'php7.3']
versions: ['latest', 'php8.1', 'php8.0', 'php7.4', 'php7.3'],
ports: {
main: 80
}
},
{
name: 'vaultwarden',
fancyName: 'Vaultwarden',
baseImage: 'vaultwarden/server',
versions: ['latest']
versions: ['latest'],
ports: {
main: 80
}
}
];

View File

@@ -2,7 +2,7 @@ import { decrypt, encrypt } from '$lib/crypto';
import { dockerInstance } from '$lib/docker';
import cuid from 'cuid';
import { generatePassword } from '.';
import { prisma, PrismaErrorHandler } from './common';
import { prisma, ErrorHandler } from './common';
import getPort from 'get-port';
import { asyncExecShell, getEngine, removeContainer } from '$lib/common';

View File

@@ -38,7 +38,7 @@ export async function configureDestinationForDatabase({ id, destinationId }) {
if (type && version) {
const baseImage = getDatabaseImage(type);
asyncExecShell(
`DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.managed="true" -t "${baseImage}:${version}" -`
`DOCKER_HOST=${host} docker pull ${baseImage}:${version} && echo "FROM ${baseImage}:${version}" | docker build --label coolify.image="true" -t "${baseImage}:${version}" -`
);
}
}
@@ -109,22 +109,4 @@ export async function setDestinationSettings({ engine, isCoolifyProxyUsed }) {
where: { engine },
data: { isCoolifyProxyUsed }
});
// if (isCoolifyProxyUsed) {
// await installCoolifyProxy(engine)
// await configureNetworkCoolifyProxy(engine)
// } else {
// // TODO: must check if other destination is using the proxy??? or not?
// const domain = await prisma.setting.findUnique({ where: { name: 'domain' }, rejectOnNotFound: false })
// if (!domain) {
// await uninstallCoolifyProxy(engine)
// } else {
// return {
// stastus: 500,
// body: {
// message: 'You can not disable the Coolify proxy while the domain is set for Coolify itself.'
// }
// }
// }
// }
}

View File

@@ -1,4 +1,4 @@
import { prisma, PrismaErrorHandler } from './common';
import { prisma, ErrorHandler } from './common';
export async function listLogs({ buildId, last = 0 }) {
try {
@@ -8,6 +8,6 @@ export async function listLogs({ buildId, last = 0 }) {
});
return [...body];
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
}

View File

@@ -97,17 +97,6 @@ export async function login({ email, password }) {
});
}
}
// const token = jsonwebtoken.sign({}, secretKey, {
// expiresIn: 15778800,
// algorithm: 'HS256',
// audience: 'coolify',
// issuer: 'coolify',
// jwtid: uid,
// subject: `User:${uid}`,
// notBefore: -1000
// });
return {
status: 200,
headers: {

View File

@@ -1,5 +1,5 @@
import { dev } from '$app/env';
import { asyncExecShell, getEngine } from '$lib/common';
import { asyncExecShell, getDomain, getEngine } from '$lib/common';
import got from 'got';
import * as db from '$lib/database';
import { letsEncrypt } from '$lib/letsencrypt';
@@ -51,11 +51,11 @@ export async function completeTransaction(transactionId) {
export async function removeProxyConfiguration({ domain }) {
const haproxy = await haproxyInstance();
const transactionId = await getNextTransactionId();
const backendFound = await haproxy
.get(`v2/services/haproxy/configuration/backends/${domain}`)
.json();
if (backendFound) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
searchParams: {
@@ -65,12 +65,13 @@ export async function removeProxyConfiguration({ domain }) {
.json();
await completeTransaction(transactionId);
}
await removeWwwRedirection(domain);
}
export async function forceSSLOffApplication({ domain }) {
if (!dev) {
const haproxy = await haproxyInstance();
await checkHAProxy(haproxy);
const transactionId = await getNextTransactionId();
let transactionId;
try {
const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
@@ -83,6 +84,8 @@ export async function forceSSLOffApplication({ domain }) {
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.cond_test.includes(`-i ${domain}`));
if (rule) {
transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: {
@@ -97,7 +100,7 @@ export async function forceSSLOffApplication({ domain }) {
} catch (error) {
console.log(error);
} finally {
await completeTransaction(transactionId);
if (transactionId) await completeTransaction(transactionId);
}
} else {
console.log(`[DEBUG] Removing ssl for ${domain}`);
@@ -106,13 +109,8 @@ export async function forceSSLOffApplication({ domain }) {
export async function forceSSLOnApplication({ domain }) {
if (!dev) {
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
const transactionId = await getNextTransactionId();
await checkHAProxy(haproxy);
let transactionId;
try {
const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
@@ -124,10 +122,14 @@ export async function forceSSLOnApplication({ domain }) {
.json();
let nextRule = 0;
if (rules.data.length > 0) {
const rule = rules.data.find((rule) => rule.cond_test.includes(`-i ${domain}`));
const rule = rules.data.find((rule) =>
rule.cond_test.includes(`{ hdr(host) -i ${domain} } !{ ssl_fc }`)
);
if (rule) return;
nextRule = rules.data[rules.data.length - 1].index + 1;
}
transactionId = await getNextTransactionId();
await haproxy
.post(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
@@ -138,7 +140,7 @@ export async function forceSSLOnApplication({ domain }) {
json: {
index: nextRule,
cond: 'if',
cond_test: `{ hdr(Host) -i ${domain} } !{ ssl_fc }`,
cond_test: `{ hdr(host) -i ${domain} } !{ ssl_fc }`,
type: 'redirect',
redir_type: 'scheme',
redir_value: 'https',
@@ -150,7 +152,7 @@ export async function forceSSLOnApplication({ domain }) {
console.log(error);
throw error;
} finally {
await completeTransaction(transactionId);
if (transactionId) await completeTransaction(transactionId);
}
} else {
console.log(`[DEBUG] Adding ssl for ${domain}`);
@@ -159,14 +161,11 @@ export async function forceSSLOnApplication({ domain }) {
export async function deleteProxy({ id }) {
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
const transactionId = await getNextTransactionId();
await checkHAProxy(haproxy);
let transactionId;
try {
await haproxy.get(`v2/services/haproxy/configuration/backends/${id}`).json();
transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${id}`, {
searchParams: {
@@ -185,108 +184,17 @@ export async function deleteProxy({ id }) {
} catch (error) {
console.log(error.response.body);
} finally {
await completeTransaction(transactionId);
if (transactionId) await completeTransaction(transactionId);
}
}
// export async function configureProxyForDatabase({ id, port, isPublic, privatePort }) {
// const haproxy = await haproxyInstance()
// try {
// await checkHAProxy()
// } catch (error) {
// return
// }
// let alreadyConfigured = false
// try {
// const backend: any = await haproxy.get(`v2/services/haproxy/configuration/backends/${id}`).json()
// const server: any = await haproxy.get(`v2/services/haproxy/configuration/servers/${id}`, {
// searchParams: {
// backend: id
// },
// }).json()
// if (backend.data.name === id) {
// if (server.data.port === privatePort) {
// if (server.data.check === 'enabled') {
// if (server.data.address === id) {
// alreadyConfigured = true
// }
// }
// }
// }
// } catch (error) {
// console.log('error getting backend or server', error.response.body)
// }
// if (alreadyConfigured) return
// const transactionId = await getNextTransactionId()
// try {
// await haproxy.post('v2/services/haproxy/configuration/backends', {
// searchParams: {
// transaction_id: transactionId
// },
// json: {
// "init-addr": "last,libc,none",
// "mode": "tcp",
// "name": id
// }
// })
// await haproxy.post('v2/services/haproxy/configuration/servers', {
// searchParams: {
// transaction_id: transactionId,
// backend: id
// },
// json: {
// "address": id,
// "check": "enabled",
// "name": id,
// "port": privatePort
// }
// })
// await haproxy.post('v2/services/haproxy/configuration/frontends', {
// searchParams: {
// transaction_id: transactionId,
// backend: id
// },
// json: {
// "default_backend": id,
// "mode": "tcp",
// "name": id
// }
// })
// await haproxy.post('v2/services/haproxy/configuration/binds', {
// searchParams: {
// transaction_id: transactionId,
// frontend: id
// },
// json: {
// "address": "*",
// "name": id,
// "port": port
// }
// })
// } catch (error) {
// console.log(error.response.body)
// throw error.response.body
// } finally {
// try {
// await completeTransaction(transactionId)
// } catch (error) {
// console.log(error.response.body)
// }
// }
// await configureDatabaseVisibility({ id, isPublic })
// }
export async function reloadHaproxy(engine) {
const host = getEngine(engine);
return await asyncExecShell(`DOCKER_HOST=${host} docker exec coolify-haproxy kill -HUP 1`);
}
export async function configureProxyForApplication({ domain, imageId, applicationId, port }) {
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
await checkHAProxy(haproxy);
let serverConfigured = false;
let backendAvailable: any = null;
@@ -308,7 +216,7 @@ export async function configureProxyForApplication({ domain, imageId, applicatio
if (backendAvailable.data.forwardfor.enabled === 'enabled') {
if (backendAvailable.data.name === domain) {
if (server.data.check === 'enabled') {
if (server.data.address === applicationId) {
if (server.data.address === imageId) {
if (server.data.port === port) {
serverConfigured = true;
}
@@ -364,17 +272,14 @@ export async function configureProxyForApplication({ domain, imageId, applicatio
}
}
export async function configureCoolifyProxyOff({ domain }) {
export async function configureCoolifyProxyOff(fqdn) {
const domain = getDomain(fqdn);
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
await checkHAProxy(haproxy);
try {
const transactionId = await getNextTransactionId();
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/backends/${domain}`, {
searchParams: {
@@ -386,25 +291,26 @@ export async function configureCoolifyProxyOff({ domain }) {
if (!dev) {
await forceSSLOffApplication({ domain });
}
await setWwwRedirection(fqdn);
} catch (error) {
throw error?.response?.body || error;
}
}
export async function checkHAProxy(haproxy) {
export async function checkHAProxy(haproxy?: any) {
if (!haproxy) haproxy = await haproxyInstance();
try {
await haproxy.get('v2/info');
} catch (error) {
throw 'HAProxy is not running, but it should be!';
throw {
message:
'Coolify Proxy is not running, but it should be!<br><br>Start it in the "Destinations" menu.'
};
}
}
export async function configureCoolifyProxyOn({ domain }) {
export async function configureCoolifyProxyOn(fqdn) {
const domain = getDomain(fqdn);
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
await checkHAProxy(haproxy);
let serverConfigured = false;
let backendAvailable: any = null;
try {
@@ -603,48 +509,65 @@ export async function configureNetworkCoolifyProxy(engine) {
export async function configureSimpleServiceProxyOn({ id, domain, port }) {
const haproxy = await haproxyInstance();
await checkHAProxy(haproxy);
let serverConfigured = false;
let backendAvailable: any = null;
try {
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
return;
backendAvailable = await haproxy
.get(`v2/services/haproxy/configuration/backends/${domain}`)
.json();
const server: any = await haproxy
.get(`v2/services/haproxy/configuration/servers/${id}`, {
searchParams: {
backend: domain
}
})
.json();
if (backendAvailable && server) {
// Very sophisticated way to check if the server is already configured in proxy
if (backendAvailable.data.forwardfor.enabled === 'enabled') {
if (backendAvailable.data.name === domain) {
if (server.data.check === 'enabled') {
if (server.data.address === id) {
if (server.data.port === port) {
serverConfigured = true;
}
}
}
}
}
}
} catch (error) {}
try {
const transactionId = await getNextTransactionId();
await haproxy.post('v2/services/haproxy/configuration/backends', {
searchParams: {
transaction_id: transactionId
},
json: {
'init-addr': 'last,libc,none',
forwardfor: { enabled: 'enabled' },
name: domain
}
});
await haproxy.post('v2/services/haproxy/configuration/servers', {
searchParams: {
transaction_id: transactionId,
backend: domain
},
json: {
address: id,
check: 'enabled',
name: id,
port: port
}
});
await completeTransaction(transactionId);
} catch (error) {
console.log(error);
}
if (serverConfigured) return;
const transactionId = await getNextTransactionId();
await haproxy.post('v2/services/haproxy/configuration/backends', {
searchParams: {
transaction_id: transactionId
},
json: {
'init-addr': 'last,libc,none',
forwardfor: { enabled: 'enabled' },
name: domain
}
});
await haproxy.post('v2/services/haproxy/configuration/servers', {
searchParams: {
transaction_id: transactionId,
backend: domain
},
json: {
address: id,
check: 'enabled',
name: id,
port: port
}
});
await completeTransaction(transactionId);
}
export async function configureSimpleServiceProxyOff({ domain }) {
const haproxy = await haproxyInstance();
try {
await checkHAProxy(haproxy);
} catch (error) {
return;
}
await checkHAProxy(haproxy);
try {
await haproxy.get(`v2/services/haproxy/configuration/backends/${domain}`).json();
const transactionId = await getNextTransactionId();
@@ -657,5 +580,90 @@ export async function configureSimpleServiceProxyOff({ domain }) {
.json();
await completeTransaction(transactionId);
} catch (error) {}
await removeWwwRedirection(domain);
return;
}
export async function removeWwwRedirection(domain) {
const haproxy = await haproxyInstance();
await checkHAProxy();
const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
if (rules.data.length > 0) {
const rule = rules.data.find((rule) =>
rule.redir_value.includes(`${domain}%[capture.req.uri]`)
);
if (rule) {
const transactionId = await getNextTransactionId();
await haproxy
.delete(`v2/services/haproxy/configuration/http_request_rules/${rule.index}`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
await completeTransaction(transactionId);
}
}
}
export async function setWwwRedirection(fqdn) {
const haproxy = await haproxyInstance();
await checkHAProxy(haproxy);
let transactionId;
try {
const domain = getDomain(fqdn);
const isHttps = fqdn.startsWith('https://');
const isWWW = fqdn.includes('www.');
const contTest = `{ req.hdr(host) -i ${isWWW ? domain.replace('www.', '') : `www.${domain}`} }`;
const rules: any = await haproxy
.get(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
parent_name: 'http',
parent_type: 'frontend'
}
})
.json();
let nextRule = 0;
if (rules.data.length > 0) {
const rule = rules.data.find((rule) =>
rule.redir_value.includes(`${domain}%[capture.req.uri]`)
);
if (rule) return;
nextRule = rules.data[rules.data.length - 1].index + 1;
}
const redirectValue = `${isHttps ? 'https://' : 'http://'}${domain}%[capture.req.uri]`;
transactionId = await getNextTransactionId();
await haproxy
.post(`v2/services/haproxy/configuration/http_request_rules`, {
searchParams: {
transaction_id: transactionId,
parent_name: 'http',
parent_type: 'frontend'
},
json: {
index: nextRule,
cond: 'if',
cond_test: contTest,
type: 'redirect',
redir_type: 'location',
redir_value: redirectValue,
redir_code: dev ? 302 : 301
}
})
.json();
} catch (error) {
console.log(error);
throw error;
} finally {
if (transactionId) await completeTransaction(transactionId);
}
}

View File

@@ -2,7 +2,7 @@ import { asyncExecShell, saveBuildLog } from '$lib/common';
import got from 'got';
import jsonwebtoken from 'jsonwebtoken';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
export default async function ({
applicationId,
@@ -45,6 +45,6 @@ export default async function ({
const { stdout: commit } = await asyncExecShell(`cd ${workdir}/ && git rev-parse HEAD`);
return commit.replace('\n', '');
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
}

View File

@@ -1,5 +1,5 @@
import { asyncExecShell, saveBuildLog } from '$lib/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
export default async function ({
applicationId,

View File

@@ -2,15 +2,17 @@ import { dev } from '$app/env';
import { forceSSLOffApplication, forceSSLOnApplication, getNextTransactionId } from '$lib/haproxy';
import { asyncExecShell, getEngine } from './common';
import * as db from '$lib/database';
import cuid from 'cuid';
export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
try {
const randomCuid = cuid();
if (dev) {
return await forceSSLOnApplication({ domain });
} else {
if (isCoolify) {
await asyncExecShell(
`docker run --rm --name certbot -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
`docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
);
const { stderr } = await asyncExecShell(
@@ -33,10 +35,10 @@ export async function letsEncrypt({ domain, isCoolify = false, id = null }) {
if (data.destinationDockerId && data.destinationDocker) {
const host = getEngine(data.destinationDocker.engine);
await asyncExecShell(
`DOCKER_HOST=${host} docker run --rm --name certbot -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
`DOCKER_HOST=${host} docker run --rm --name certbot-${randomCuid} -p 9080:9080 -v "coolify-letsencrypt:/etc/letsencrypt" certbot/certbot --logs-dir /etc/letsencrypt/logs certonly --standalone --preferred-challenges http --http-01-address 0.0.0.0 --http-01-port 9080 -d ${domain} --agree-tos --non-interactive --register-unsafely-without-email`
);
const { stderr } = await asyncExecShell(
`DOCKER_HOST=${host} docker run --rm --name bash -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem`
`DOCKER_HOST=${host} docker run --rm --name bash-${randomCuid} -v "coolify-letsencrypt:/etc/letsencrypt" -v "coolify-ssl-certs:/app/ssl" alpine:latest cat /etc/letsencrypt/live/${domain}/fullchain.pem /etc/letsencrypt/live/${domain}/privkey.pem > /app/ssl/${domain}.pem`
);
if (stderr) throw new Error(stderr);
await forceSSLOnApplication({ domain });

View File

@@ -4,7 +4,7 @@ import * as buildpacks from '../buildPacks';
import * as importers from '../importers';
import { dockerInstance } from '../docker';
import { asyncExecShell, createDirectories, getDomain, getEngine, saveBuildLog } from '../common';
import { configureProxyForApplication, reloadHaproxy } from '../haproxy';
import { configureProxyForApplication, reloadHaproxy, setWwwRedirection } from '../haproxy';
import * as db from '$lib/database';
import { decrypt } from '$lib/crypto';
import { sentry } from '$lib/common';
@@ -64,10 +64,6 @@ export default async function (job) {
if (destinationDockerId) {
destinationType = 'docker';
}
// Not implemented yet
// if (destinationKubernetesId) {
// destinationType = 'kubernetes'
// }
if (destinationType === 'docker') {
const docker = dockerInstance({ destinationDocker });
@@ -209,9 +205,7 @@ export default async function (job) {
const envs = [];
if (secrets.length > 0) {
secrets.forEach((secret) => {
if (!secret.isBuildSecret) {
envs.push(`${secret.name}=${secret.value}`);
}
envs.push(`${secret.name}=${secret.value}`);
});
}
await fs.writeFile(`${workdir}/.env`, envs.join('\n'));
@@ -252,6 +246,7 @@ export default async function (job) {
saveBuildLog({ line: 'Proxy configuration started!', buildId, applicationId });
await configureProxyForApplication({ domain, imageId, applicationId, port });
if (isHttps) await letsEncrypt({ domain, id: applicationId });
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
saveBuildLog({ line: 'Proxy configuration successful!', buildId, applicationId });
} else {

View File

@@ -23,7 +23,7 @@ export default async function () {
];
for (const image of images) {
await asyncExecShell(
`DOCKER_HOST=${host} docker pull ${image} && echo "FROM ${image}" | docker build --label coolify.managed="true" -t "${image}" -`
`DOCKER_HOST=${host} docker pull ${image} && echo "FROM ${image}" | docker build --label coolify.image="true" -t "${image}" -`
);
}
} catch (error) {}
@@ -35,11 +35,17 @@ export default async function () {
// Cleanup images that are not managed by coolify
try {
await asyncExecShell(
`DOCKER_HOST=${host} docker image prune --filter 'label!=coolify.managed=true' -a -f`
`DOCKER_HOST=${host} docker image prune --filter 'label!=coolify.image=true' -a -f`
);
} catch (error) {
console.log(error);
}
// Cleanup dangling images
try {
await asyncExecShell(`DOCKER_HOST=${host} docker image prune -f`);
} catch (error) {
console.log(error);
}
}
}
}

View File

@@ -87,7 +87,7 @@ const cron = async () => {
await queue.proxy.add('proxy', {}, { repeat: { every: 10000 } });
// await queue.ssl.add('ssl', {}, { repeat: { every: 10000 } });
await queue.cleanup.add('cleanup', {}, { repeat: { every: 3600000 } });
if (!dev) await queue.cleanup.add('cleanup', {}, { repeat: { every: 600000 } });
await queue.sslRenew.add('sslRenew', {}, { repeat: { every: 1800000 } });
const events = {
@@ -144,29 +144,7 @@ buildWorker.on('failed', async (job: Bullmq.Job, failedReason) => {
});
});
// const letsEncryptQueueName = dev ? cuid() : 'letsencrypt_queue'
// const letsEncryptQueue = new Queue(letsEncryptQueueName, connectionOptions)
// const letsEncryptWorker = new Worker(letsEncryptQueueName, async (job) => await letsencrypt(job), {
// concurrency: 1,
// ...connectionOptions
// })
// letsEncryptWorker.on('completed', async () => {
// // TODO: Save letsencrypt logs as build logs!
// console.log('[DEBUG] Lets Encrypt job completed')
// })
// letsEncryptWorker.on('failed', async (job: Job, failedReason: string) => {
// try {
// await prisma.applicationSettings.updateMany({ where: { applicationId: job.data.id }, data: { forceSSL: false } })
// } catch (error) {
// console.log(error)
// }
// console.log('[DEBUG] Lets Encrypt job failed')
// console.log(failedReason)
// })
const buildLogQueueName = dev ? cuid() : 'log_queue';
const buildLogQueueName = 'log_queue';
const buildLogQueue = new Queue(buildLogQueueName, connectionOptions);
const buildLogWorker = new Worker(buildLogQueueName, async (job) => await logger(job), {
concurrency: 1,

View File

@@ -1,13 +1,16 @@
import { getDomain } from '$lib/common';
import { prisma } from '$lib/database';
import { getApplicationById, prisma, supportedServiceTypesAndVersions } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import {
checkContainer,
configureCoolifyProxyOn,
configureProxyForApplication,
configureSimpleServiceProxyOn,
forceSSLOnApplication,
reloadHaproxy,
startCoolifyProxy
setWwwRedirection,
startCoolifyProxy,
startHttpProxy
} from '$lib/haproxy';
import * as db from '$lib/database';
@@ -23,42 +26,82 @@ export default async function () {
(container) => container.Labels['coolify.managed']
);
for (const configuration of configurations) {
const parsedConfiguration = JSON.parse(
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
);
if (configuration.Labels['coolify.type'] === 'standalone-application') {
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration;
if (fqdn) {
const domain = getDomain(fqdn);
await configureProxyForApplication({
domain,
imageId: pullmergeRequestId
? `${applicationId}-${pullmergeRequestId}`
: applicationId,
applicationId,
port
});
const isHttps = fqdn.startsWith('https://');
if (isHttps) await forceSSLOnApplication({ domain });
if (configuration.Labels['coolify.configuration']) {
const parsedConfiguration = JSON.parse(
Buffer.from(configuration.Labels['coolify.configuration'], 'base64').toString()
);
if (
parsedConfiguration &&
configuration.Labels['coolify.type'] === 'standalone-application'
) {
const { fqdn, applicationId, port, pullmergeRequestId } = parsedConfiguration;
if (fqdn) {
const found = await getApplicationById({ id: applicationId });
if (found) {
const domain = getDomain(fqdn);
await configureProxyForApplication({
domain,
imageId: pullmergeRequestId
? `${applicationId}-${pullmergeRequestId}`
: applicationId,
applicationId,
port
});
const isHttps = fqdn.startsWith('https://');
if (isHttps) await forceSSLOnApplication({ domain });
await setWwwRedirection(fqdn);
}
}
}
}
}
for (const container of containers) {
const image = container.Image.split(':')[0];
const found = supportedServiceTypesAndVersions.find((a) => a.baseImage === image);
if (found) {
const type = found.name;
const mainPort = found.ports.main;
const id = container.Names[0].replace('/', '');
const service = await db.prisma.service.findUnique({
where: { id },
include: {
destinationDocker: true,
minio: true,
plausibleAnalytics: true,
vscodeserver: true,
wordpress: true
}
});
const { fqdn } = service;
const domain = getDomain(fqdn);
await configureSimpleServiceProxyOn({ id, domain, port: mainPort });
const publicPort = service[type]?.publicPort;
if (publicPort) {
const containerFound = await checkContainer(
destination.engine,
`haproxy-for-${publicPort}`
);
if (!containerFound) {
await startHttpProxy(destination, id, publicPort, 9000);
}
}
}
}
}
}
const services = await prisma.service.findMany({});
// Check Coolify FQDN and configure proxy if needed
const { fqdn } = await db.listSettings();
if (fqdn) {
const domain = getDomain(fqdn);
const found = await checkContainer('/var/run/docker.sock', 'coolify-haproxy');
if (!found) await startCoolifyProxy('/var/run/docker.sock');
await configureCoolifyProxyOn({ domain });
await startCoolifyProxy('/var/run/docker.sock');
await configureCoolifyProxyOn(fqdn);
await setWwwRedirection(fqdn);
const isHttps = fqdn.startsWith('https://');
if (isHttps) await forceSSLOnApplication({ domain });
}
} catch (error) {
console.log(error);
throw error;
} finally {
// await reloadHaproxy('/var/run/docker.sock');
}
}

View File

@@ -96,10 +96,9 @@
async function update() {
updateStatus.loading = true;
// if (!dev) {
try {
await post(`/update.json`, { type: 'update', latestVersion });
toast.push('Update completed. Waiting for the new version to start...');
toast.push('Update completed.<br>Waiting for the new version to start...');
let reachable = false;
let tries = 0;
do {
@@ -119,30 +118,10 @@
await asyncSleep(3000);
return window.location.reload();
} catch ({ error }) {
return errorNotification(error);
} finally {
updateStatus.success = false;
updateStatus.loading = false;
return errorNotification(error);
}
// } else {
// let reachable = false;
// let tries = 0;
// do {
// await asyncSleep(1000);
// try {
// await get(`/undead.json`);
// reachable = true;
// } catch (error) {
// console.log(error);
// reachable = false;
// }
// if (reachable) break;
// tries++;
// } while (!reachable || tries < 120);
// toast.push('New version reachable. Reloading...');
// await asyncSleep(2000);
// window.location.reload();
// }
}
</script>

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getDomain, getEngine, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -23,6 +23,6 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -74,13 +74,18 @@
}
async function isBranchAlreadyUsed() {
try {
return await get(
const data = await get(
`/applications/${id}/configuration/repository.json?repository=${selected.repository}&branch=${selected.branch}`
);
} catch ({ error }) {
return errorNotification(error);
} finally {
if (data.used) {
errorNotification('This branch is already used by another application.');
showSave = false;
return true;
}
showSave = true;
} catch ({ error }) {
showSave = false;
return errorNotification(error);
}
}

View File

@@ -132,24 +132,20 @@
}
async function isBranchAlreadyUsed() {
const url = `/applications/${id}/configuration/repository.json?repository=${selected.project.path_with_namespace}&branch=${selected.branch.name}`;
try {
await get(url);
const data = await get(
`/applications/${id}/configuration/repository.json?repository=${selected.project.path_with_namespace}&branch=${selected.branch.name}`
);
if (data.used) {
errorNotification('This branch is already used by another application.');
showSave = false;
return true;
}
showSave = true;
} catch (error) {
showSave = false;
return errorNotification('Branch already configured');
} catch ({ error }) {
return errorNotification(error);
}
}
// async function saveDeployKey(deployKeyId: number) {
// try {
// await post(updateDeployKeyIdUrl, { deployKeyId });
// } catch (error) {
// errorNotification(error);
// throw new Error(error);
// }
// }
async function checkSSHKey(sshkeyUrl) {
try {
return await post(sshkeyUrl, {});
@@ -203,7 +199,6 @@
const deployKeyFound = deployKeys.filter((dk) => dk.title === `${appId}-coolify-deploy-key`);
if (deployKeyFound.length > 0) {
for (const deployKey of deployKeyFound) {
console.log(`${deployKeyUrl}/${deployKey.id}`);
await del(
`${deployKeyUrl}/${deployKey.id}`,
{},

View File

@@ -1,7 +1,7 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
export const get: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -21,7 +21,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -36,6 +36,6 @@ export const post: RequestHandler = async (event) => {
await db.configureBuildPack({ id, buildPack });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -12,6 +12,6 @@ export const post: RequestHandler = async (event) => {
await db.updateDeployKey({ id, deployKeyId });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
await db.configureDestinationForApplication({ id, destinationId });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -14,16 +14,14 @@ export const get: RequestHandler = async (event) => {
try {
const found = await db.isBranchAlreadyUsed({ repository, branch, id });
if (found) {
throw {
error: `Branch ${branch} is already used by another application`
};
}
return {
status: 200
status: 200,
body: {
used: found ? true : false
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -42,6 +40,6 @@ export const post: RequestHandler = async (event) => {
await db.configureGitRepository({ id, repository, branch, projectId, webhookToken });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,6 +13,6 @@ export const post: RequestHandler = async (event) => {
await db.configureGitsource({ id, gitSourceId });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -7,7 +7,7 @@ export const get: RequestHandler = async (event) => {
try {
return await db.getSshKey({ id });
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
export const post: RequestHandler = async (event) => {
@@ -15,6 +15,6 @@ export const post: RequestHandler = async (event) => {
try {
return await db.generateSshKey({ id });
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const del: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const del: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,7 +4,7 @@ import cuid from 'cuid';
import crypto from 'crypto';
import { buildQueue } from '$lib/queues';
import { getUserDetails } from '$lib/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -37,6 +37,6 @@ export const post: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,7 +1,7 @@
import { getTeam, getUserDetails } from '$lib/common';
import { getGithubToken } from '$lib/components/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { checkContainer } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
import jsonwebtoken from 'jsonwebtoken';
@@ -44,7 +44,7 @@ export const get: RequestHandler = async (event) => {
};
} catch (error) {
console.log(error);
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -82,6 +82,6 @@ export const post: RequestHandler = async (event) => {
});
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -266,7 +266,7 @@
required
/>
<Explainer
text="If you specify <span class='text-green-600 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>To modify the domain, you must first stop the application."
text="If you specify <span class='text-green-600 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-green-600 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application."
/>
</div>
</div>

View File

@@ -15,16 +15,32 @@
let loading = true;
let currentStatus;
let streamInterval;
let followingBuild;
let followingInterval;
let logsEl;
const { id } = $page.params;
const cleanAnsiCodes = (str: string) => str.replace(/\x1B\[(\d+)m/g, '');
function followBuild() {
followingBuild = !followingBuild;
if (followingBuild) {
followingInterval = setInterval(() => {
logsEl.scrollTop = logsEl.scrollHeight;
window.scrollTo(0, document.body.scrollHeight);
}, 100);
} else {
window.clearInterval(followingInterval);
}
}
async function streamLogs(sequence = 0) {
try {
let { logs: responseLogs, status } = await get(
`/applications/${id}/logs/build/build.json?buildId=${buildId}&sequence=${sequence}`
);
currentStatus = status;
logs = logs.concat(responseLogs);
logs = logs.concat(responseLogs.map((log) => ({ ...log, line: cleanAnsiCodes(log.line) })));
loading = false;
streamInterval = setInterval(async () => {
if (status !== 'running') {
@@ -38,18 +54,21 @@
);
status = data.status;
currentStatus = status;
logs = logs.concat(data.logs);
logs = logs.concat(data.logs.map((log) => ({ ...log, line: cleanAnsiCodes(log.line) })));
dispatch('updateBuildStatus', { status });
} catch ({ error }) {
return errorNotification(error);
}
}, 1000);
} catch ({ error }) {
console.log(error);
return errorNotification(error);
}
}
onDestroy(() => {
clearInterval(streamInterval);
clearInterval(followingInterval);
});
onMount(async () => {
window.scrollTo(0, 0);
@@ -60,12 +79,37 @@
{#if loading}
<Loading />
{:else}
<div class="relative">
<div class="relative ">
{#if currentStatus === 'running'}
<LoadingLogs />
{/if}
<div class="flex justify-end sticky top-0 p-2">
<button
on:click={followBuild}
data-tooltip="Follow logs"
class:text-green-500={followingBuild}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<circle cx="12" cy="12" r="9" />
<line x1="8" y1="12" x2="12" y2="16" />
<line x1="12" y1="8" x2="12" y2="16" />
<line x1="16" y1="12" x2="12" y2="16" />
</svg>
</button>
</div>
<div
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words"
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12"
bind:this={logsEl}
>
{#each logs as log}
<div>{log.line + '\n'}</div>

View File

@@ -1,6 +1,6 @@
import { getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -23,6 +23,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dayjs } from '$lib/dayjs';
import type { RequestHandler } from '@sveltejs/kit';
@@ -35,6 +35,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -33,7 +33,6 @@
export let buildCount;
let buildId;
$: buildId;
let skip = 0;
let noMoreBuilds = buildCount < 5 || buildCount <= skip;
@@ -92,45 +91,47 @@
Build logs of <a href={application.fqdn} target="_blank">{getDomain(application.fqdn)}</a>
</div>
</div>
<div class="flex flex-row justify-start space-x-2 px-10 pt-6 ">
<div class="min-w-[16rem] space-y-2">
{#each builds as build (build.id)}
<div
data-tooltip={new Intl.DateTimeFormat('default', dateOptions).format(
new Date(build.createdAt)
) + `\n${build.status}`}
on:click={() => loadBuild(build.id)}
class="tooltip-top flex cursor-pointer items-center justify-center rounded-r border-l-2 border-transparent py-4 no-underline transition-all duration-100 hover:bg-coolgray-400 hover:shadow-xl"
class:bg-coolgray-400={buildId === build.id}
class:border-red-500={build.status === 'failed'}
class:border-green-500={build.status === 'success'}
class:border-yellow-500={build.status === 'inprogress'}
>
<div class="flex-col px-2">
<div class="text-sm font-bold">
{application.branch}
<div class="block flex-row justify-start space-x-2 px-5 pt-6 sm:px-10 md:flex">
<div class="mb-4 min-w-[16rem] space-y-2 md:mb-0 ">
<div class="top-4 md:sticky">
{#each builds as build (build.id)}
<div
data-tooltip={new Intl.DateTimeFormat('default', dateOptions).format(
new Date(build.createdAt)
) + `\n${build.status}`}
on:click={() => loadBuild(build.id)}
class="tooltip-top flex cursor-pointer items-center justify-center rounded-r border-l-2 border-transparent py-4 no-underline transition-all duration-100 hover:bg-coolgray-400 hover:shadow-xl "
class:bg-coolgray-400={buildId === build.id}
class:border-red-500={build.status === 'failed'}
class:border-green-500={build.status === 'success'}
class:border-yellow-500={build.status === 'inprogress'}
>
<div class="flex-col px-2">
<div class="text-sm font-bold">
{application.branch}
</div>
<div class="text-xs">
{build.type}
</div>
</div>
<div class="text-xs">
{build.type}
</div>
</div>
<div class="flex-1" />
<div class="flex-1" />
<div class="w-48 text-center text-xs">
{#if build.status === 'running'}
<div class="font-bold">Running</div>
{:else}
<div>{build.since}</div>
<div>Finished in <span class="font-bold">{build.took}s</span></div>
{/if}
<div class="w-48 text-center text-xs">
{#if build.status === 'running'}
<div class="font-bold">Running</div>
{:else}
<div>{build.since}</div>
<div>Finished in <span class="font-bold">{build.took}s</span></div>
{/if}
</div>
</div>
</div>
{/each}
{#if buildCount > 0 && !noMoreBuilds}
<button class="w-full" on:click={loadMoreBuilds}>Load More</button>
{/if}
{/each}
</div>
<div class="flex space-x-2">
<button disabled={noMoreBuilds} class="w-full" on:click={loadMoreBuilds}>Load More</button>
</div>
</div>
<div class="w-96 flex-1">
<div class="flex-1 md:w-96">
{#if buildId}
{#key buildId}
<svelte:component this={BuildLog} {buildId} on:updateBuildStatus={updateBuildStatus} />

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dayjs } from '$lib/dayjs';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
@@ -48,6 +48,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -27,19 +27,23 @@
import { getDomain } from '$lib/components/common';
import { get } from '$lib/api';
import { errorNotification } from '$lib/form';
let loadLogsInterval = null;
let logs = [];
let followingBuild;
let followingInterval;
let logsEl;
const { id } = $page.params;
onMount(async () => {
loadLogs();
loadLogsInterval = setInterval(() => {
loadLogs();
}, 3000);
}, 1000);
});
onDestroy(() => {
clearInterval(loadLogsInterval);
clearInterval(followingInterval);
});
async function loadLogs() {
try {
@@ -50,6 +54,18 @@
return errorNotification(error);
}
}
function followBuild() {
followingBuild = !followingBuild;
if (followingBuild) {
followingInterval = setInterval(() => {
logsEl.scrollTop = logsEl.scrollHeight;
window.scrollTo(0, document.body.scrollHeight);
}, 100);
} else {
window.clearInterval(followingInterval);
}
}
</script>
<div class="flex space-x-1 p-6 font-bold">
@@ -63,8 +79,33 @@
{:else}
<div class="relative w-full">
<LoadingLogs />
<div class="flex justify-end sticky top-0 p-2">
<button
on:click={followBuild}
data-tooltip="Follow logs"
class:text-green-500={followingBuild}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<circle cx="12" cy="12" r="9" />
<line x1="8" y1="12" x2="12" y2="16" />
<line x1="12" y1="8" x2="12" y2="16" />
<line x1="16" y1="12" x2="12" y2="16" />
</svg>
</button>
</div>
<div
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 p-6 whitespace-pre-wrap break-words w-full"
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 p-6 whitespace-pre-wrap break-words w-full mb-10 -mt-12"
bind:this={logsEl}
>
{#each logs as log}
{log + '\n'}

View File

@@ -1,6 +1,6 @@
import { getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
import jsonwebtoken from 'jsonwebtoken';
@@ -39,6 +39,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -9,7 +9,8 @@
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
let nameEl;
let valueEl;
const { id } = $page.params;
async function removeSecret() {
try {
@@ -18,18 +19,29 @@
if (isNewSecret) {
name = '';
value = '';
isBuildSecret = false;
}
} catch ({ error }) {
return errorNotification(error);
}
}
async function saveSecret() {
const nameValid = nameEl.checkValidity();
const valueValid = valueEl.checkValidity();
if (!nameValid) {
return nameEl.reportValidity();
}
if (!valueValid) {
return valueEl.reportValidity();
}
try {
await post(`/applications/${id}/secrets.json`, { name, value, isBuildSecret });
dispatch('refresh');
if (isNewSecret) {
name = '';
value = '';
isBuildSecret = false;
}
} catch ({ error }) {
return errorNotification(error);
@@ -45,7 +57,9 @@
<td class="whitespace-nowrap px-6 py-2 text-sm font-medium text-white">
<input
id="secretName"
bind:this={nameEl}
bind:value={name}
required
placeholder="EXAMPLE_VARIABLE"
class="-mx-2 w-64 border-2 border-transparent"
readonly={!isNewSecret}
@@ -57,6 +71,8 @@
<input
id="secretValue"
bind:value
bind:this={valueEl}
required
placeholder="J$#@UIO%HO#$U%H"
class="-mx-2 w-64 border-2 border-transparent"
class:bg-transparent={!isNewSecret}

View File

@@ -1,6 +1,6 @@
import { getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -18,7 +18,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -42,7 +42,7 @@ export const post: RequestHandler = async (event) => {
};
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
export const del: RequestHandler = async (event) => {
@@ -58,6 +58,6 @@ export const del: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
await db.setApplicationSettings({ id, debug, previews });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getDomain, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { removeProxyConfiguration } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -26,6 +26,6 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -16,6 +16,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
await db.configureDestinationForDatabase({ id, destinationId });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, supportedDatabaseTypesAndVersions } from '$lib/database';
import { ErrorHandler, supportedDatabaseTypesAndVersions } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -27,6 +27,6 @@ export const post: RequestHandler = async (event) => {
status: 201
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, supportedDatabaseTypesAndVersions } from '$lib/database';
import { ErrorHandler, supportedDatabaseTypesAndVersions } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -31,6 +31,6 @@ export const post: RequestHandler = async (event) => {
status: 201
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, stopDatabase } from '$lib/database';
import { ErrorHandler, stopDatabase } from '$lib/database';
import { deleteProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -17,6 +17,6 @@ export const del: RequestHandler = async (event) => {
await db.removeDatabase({ id });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getEngine, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { generateDatabaseConfiguration, getVersions, PrismaErrorHandler } from '$lib/database';
import { generateDatabaseConfiguration, getVersions, ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -25,9 +25,7 @@ export const get: RequestHandler = async (event) => {
state = 'running';
}
} catch (error) {
// if (!error.stderr.includes('No such object')) {
// console.log(error)
// }
//
}
}
const configuration = generateDatabaseConfiguration(database);
@@ -42,7 +40,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -66,6 +64,6 @@ export const post: RequestHandler = async (event) => {
});
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { generateDatabaseConfiguration, PrismaErrorHandler } from '$lib/database';
import { generateDatabaseConfiguration, ErrorHandler } from '$lib/database';
import { startTcpProxy, stopTcpHttpProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -29,6 +29,6 @@ export const post: RequestHandler = async (event) => {
status: 201
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, createDirectories, getEngine, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { generateDatabaseConfiguration, PrismaErrorHandler } from '$lib/database';
import { generateDatabaseConfiguration, ErrorHandler } from '$lib/database';
import { promises as fs } from 'fs';
import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
@@ -77,6 +77,6 @@ export const post: RequestHandler = async (event) => {
};
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, stopDatabase } from '$lib/database';
import { ErrorHandler, stopDatabase } from '$lib/database';
import { stopTcpHttpProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -20,6 +20,6 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -15,6 +15,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -14,6 +14,7 @@
let cannotDisable = settings.fqdn && destination.engine === '/var/run/docker.sock';
// let scannedApps = [];
let loading = false;
let restarting = false;
async function handleSubmit() {
loading = true;
try {
@@ -42,6 +43,17 @@
} catch ({ error }) {
return errorNotification(error);
}
} else if (state === true && destination.isCoolifyProxyUsed === false) {
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
try {
await post(`/destinations/${id}/settings.json`, {
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
engine: destination.engine
});
await startProxy();
} catch ({ error }) {
return errorNotification(error);
}
}
});
async function changeProxySetting() {
@@ -89,6 +101,25 @@
return errorNotification(error);
}
}
async function forceRestartProxy() {
const sure = confirm(
'Are you sure you want to restart the proxy? Everyting will be reconfigured in ~10 sec.'
);
if (sure) {
try {
restarting = true;
toast.push('Coolify Proxy restarting...');
await post(`/destinations/${id}/restart.json`, {
engine: destination.engine,
fqdn: settings.fqdn
});
} catch ({ error }) {
setTimeout(() => {
window.location.reload();
}, 5000);
}
}
}
</script>
<div class="flex justify-center px-6 pb-8">
@@ -103,6 +134,12 @@
disabled={loading}
>{loading ? 'Saving...' : 'Save'}
</button>
<button
class={restarting ? '' : 'bg-red-600 hover:bg-red-500'}
disabled={restarting}
on:click|preventDefault={forceRestartProxy}
>{restarting ? 'Restarting... please wait...' : 'Force restart proxy'}</button
>
<!-- <button type="button" class="bg-coollabs hover:bg-coollabs-100" on:click={scanApps}
>Scan for applications</button
> -->

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getEngine, getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { checkContainer } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -23,7 +23,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
export const post: RequestHandler = async (event) => {
@@ -37,7 +37,7 @@ export const post: RequestHandler = async (event) => {
await db.updateDestination({ id, name, engine, network });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -51,6 +51,6 @@ export const del: RequestHandler = async (event) => {
await db.removeDestination({ id });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -0,0 +1,34 @@
import { getDomain, getUserDetails } from '$lib/common';
import { ErrorHandler } from '$lib/database';
import * as db from '$lib/database';
import {
configureCoolifyProxyOn,
forceSSLOnApplication,
setWwwRedirection,
startCoolifyProxy,
stopCoolifyProxy
} from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
if (status === 401) return { status, body };
const { engine, fqdn } = await event.request.json();
try {
const domain = getDomain(fqdn);
await stopCoolifyProxy(engine);
await startCoolifyProxy(engine);
await db.setDestinationSettings({ engine, isCoolifyProxyUsed: true });
await configureCoolifyProxyOn(fqdn);
await setWwwRedirection(fqdn);
const isHttps = fqdn.startsWith('https://');
if (isHttps) await forceSSLOnApplication({ domain });
return {
status: 200
};
} catch (error) {
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
@@ -59,6 +59,6 @@ export const post: RequestHandler = async (event) => {
status: 404
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,6 +13,6 @@ export const post: RequestHandler = async (event) => {
await db.setDestinationSettings({ engine, isCoolifyProxyUsed });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import { getUserDetails } from '$lib/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { startCoolifyProxy, stopCoolifyProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -16,6 +16,6 @@ export const post: RequestHandler = async (event) => {
};
} catch (error) {
await stopCoolifyProxy(engine);
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import { getUserDetails } from '$lib/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { stopCoolifyProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (request) => {
@@ -14,6 +14,6 @@ export const get: RequestHandler = async (request) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getTeam, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -25,7 +25,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,7 +13,7 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -28,6 +28,6 @@ export const get: RequestHandler = async (event) => {
await db.getUser({ userId });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -24,6 +24,6 @@ export const post: RequestHandler = async (event) => {
});
return { status: 201, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails, uniqueName } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
const { id } = await db.newApplication({ name, teamId });
return { status: 201, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,6 +13,6 @@ export const post: RequestHandler = async (event) => {
const { id } = await db.newDatabase({ name, teamId });
return { status: 201, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,5 +1,5 @@
import { getUserDetails } from '$lib/common';
import { isDockerNetworkExists, PrismaErrorHandler } from '$lib/database';
import { isDockerNetworkExists, ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -18,6 +18,6 @@ export const post: RequestHandler = async (event) => {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
const id = await db.newDestination({ name, teamId, engine, network, isCoolifyProxyUsed });
return { status: 200, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails, uniqueName } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,6 +13,6 @@ export const post: RequestHandler = async (event) => {
const { id } = await db.newService({ name, teamId });
return { status: 201, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -12,6 +12,6 @@ export const post: RequestHandler = async (event) => {
const { id } = await db.newSource({ name, teamId, type, htmlUrl, apiUrl, organization });
return { status: 201, body: { id } };
} catch (e) {
return PrismaErrorHandler(e);
return ErrorHandler(e);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails, uniqueName } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -13,6 +13,6 @@ export const post: RequestHandler = async (event) => {
const { id } = await db.newTeam({ name, userId });
return { status: 201, body: { id } };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -110,25 +110,9 @@
required
/>
<Explainer
text="If you specify <span class='text-green-600 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you."
text="If you specify <span class='text-pink-600 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-pink-600 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application."
/>
</div>
<!-- {:else}
<label for="fqdn" class="pt-2">Domain (FQDN)</label>
<div class="col-span-2 ">
<CopyPasswordField
placeholder="eg: https://analytics.coollabs.io"
readonly={!$session.isAdmin}
name="fqdn"
id="fqdn"
bind:value={service.fqdn}
required
/>
<Explainer
text="If you specify <span class='text-green-600'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you."
/>
</div>
{/if} -->
</div>
{#if service.type === 'plausibleanalytics'}
<PlausibleAnalytics bind:service {readOnly} />

View File

@@ -110,23 +110,23 @@
loading = false;
}
}
onMount(async () => {
if (
service.type &&
service.destinationDockerId &&
service.version &&
service.fqdn &&
!isRunning
) {
try {
await post(`/services/${service.id}/${service.type}/stop.json`, {});
} catch ({ error }) {
return errorNotification(error);
} finally {
loading = false;
}
}
});
// onMount(async () => {
// if (
// service.type &&
// service.destinationDockerId &&
// service.version &&
// service.fqdn &&
// !isRunning
// ) {
// try {
// await post(`/services/${service.id}/${service.type}/stop.json`, {});
// } catch ({ error }) {
// return errorNotification(error);
// } finally {
// loading = false;
// }
// }
// });
</script>
<nav class="nav-side">

View File

@@ -1,6 +1,6 @@
import { asyncExecShell, getDomain, getEngine, getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -21,6 +21,6 @@ export const post: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -14,6 +14,6 @@ export const post: RequestHandler = async (event) => {
await db.configureDestinationForService({ id, destinationId });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, supportedServiceTypesAndVersions } from '$lib/database';
import { ErrorHandler, supportedServiceTypesAndVersions } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -27,6 +27,6 @@ export const post: RequestHandler = async (event) => {
status: 201
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler, supportedServiceTypesAndVersions } from '$lib/database';
import { ErrorHandler, supportedServiceTypesAndVersions } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const get: RequestHandler = async (event) => {
@@ -18,7 +18,7 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
@@ -35,6 +35,6 @@ export const post: RequestHandler = async (event) => {
status: 201
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const del: RequestHandler = async (events) => {
@@ -13,6 +13,6 @@ export const del: RequestHandler = async (events) => {
await db.removeService({ id });
return { status: 200 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,7 +4,7 @@ import {
generateDatabaseConfiguration,
getServiceImage,
getVersions,
PrismaErrorHandler
ErrorHandler
} from '$lib/database';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
@@ -43,27 +43,6 @@ export const get: RequestHandler = async (event) => {
}
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};
// export const post: RequestHandler<Locals, FormData> = async (request) => {
// const { teamId, status, body } = await getUserDetails(request);
// if (status === 401) return { status, body }
// const { id } = request.params
// const name = request.body.get('name')
// const defaultDatabase = request.body.get('defaultDatabase')
// const dbUser = request.body.get('dbUser')
// const dbUserPassword = request.body.get('dbUserPassword')
// const rootUser = request.body.get('rootUser')
// const rootUserPassword = request.body.get('rootUserPassword')
// const version = request.body.get('version')
// try {
// return await db.updateDatabase({ id, name, defaultDatabase, dbUser, dbUserPassword, rootUser, rootUserPassword, version })
// } catch (err) {
// return err
// }
// }

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -16,6 +16,6 @@ export const post: RequestHandler = async (event) => {
await db.updateNocoDbOrMinioService({ id, fqdn, name });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -5,14 +5,17 @@ import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
import { letsEncrypt } from '$lib/letsencrypt';
import {
checkHAProxy,
configureSimpleServiceProxyOn,
reloadHaproxy,
setWwwRedirection,
startHttpProxy,
startTcpProxy
} from '$lib/haproxy';
import getPort from 'get-port';
import { getDomain } from '$lib/components/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { makeLabelForServices } from '$lib/buildPacks/common';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -21,6 +24,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params;
try {
await checkHAProxy();
const service = await db.getService({ id, teamId });
const {
type,
@@ -60,7 +64,8 @@ export const post: RequestHandler = async (event) => {
environment: config.environmentVariables,
networks: [network],
volumes: [config.volume],
restart: 'always'
restart: 'always',
labels: makeLabelForServices('minio')
}
},
networks: {
@@ -86,22 +91,22 @@ export const post: RequestHandler = async (event) => {
try {
await asyncExecShell(`DOCKER_HOST=${host} docker compose -f ${composeFileDestination} up -d`);
await configureSimpleServiceProxyOn({ id, domain, port: consolePort });
await db.updateMinioService({ id, publicPort });
await startHttpProxy(destinationDocker, id, publicPort, apiPort);
if (isHttps) {
await letsEncrypt({ domain, id });
}
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
return {
status: 200
};
} catch (error) {
console.log(error);
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,7 +1,7 @@
import { getEngine, getUserDetails, removeDestinationDocker } from '$lib/common';
import { getDomain } from '$lib/components/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { checkContainer, configureSimpleServiceProxyOff, stopTcpHttpProxy } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -33,14 +33,18 @@ export const post: RequestHandler = async (event) => {
} catch (error) {
console.error(error);
}
await stopTcpHttpProxy(destinationDocker, publicPort);
await configureSimpleServiceProxyOff({ domain });
try {
await stopTcpHttpProxy(destinationDocker, publicPort);
await configureSimpleServiceProxyOff({ domain });
} catch (error) {
console.log(error);
}
}
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -15,6 +15,6 @@ export const post: RequestHandler = async (event) => {
await db.updateNocoDbOrMinioService({ id, fqdn, name });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,9 +4,15 @@ import { promises as fs } from 'fs';
import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
import { letsEncrypt } from '$lib/letsencrypt';
import { configureSimpleServiceProxyOn, reloadHaproxy } from '$lib/haproxy';
import {
checkHAProxy,
configureSimpleServiceProxyOn,
reloadHaproxy,
setWwwRedirection
} from '$lib/haproxy';
import { getDomain } from '$lib/components/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { makeLabelForServices } from '$lib/buildPacks/common';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -15,6 +21,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params;
try {
await checkHAProxy();
const service = await db.getService({ id, teamId });
const { type, version, fqdn, destinationDockerId, destinationDocker } = service;
@@ -33,7 +40,8 @@ export const post: RequestHandler = async (event) => {
container_name: id,
image: `nocodb/nocodb:${version}`,
networks: [network],
restart: 'always'
restart: 'always',
labels: makeLabelForServices('nocodb')
}
},
networks: {
@@ -52,15 +60,15 @@ export const post: RequestHandler = async (event) => {
if (isHttps) {
await letsEncrypt({ domain, id });
}
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
return {
status: 200
};
} catch (error) {
console.log(error);
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,7 +1,7 @@
import { getUserDetails, removeDestinationDocker } from '$lib/common';
import { getDomain } from '$lib/components/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -27,13 +27,17 @@ export const post: RequestHandler = async (event) => {
} catch (error) {
console.error(error);
}
await configureSimpleServiceProxyOff({ domain });
try {
await configureSimpleServiceProxyOff({ domain });
} catch (error) {
console.log(error);
}
}
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import type { RequestHandler } from '@sveltejs/kit';
@@ -28,6 +28,6 @@ export const post: RequestHandler = async (event) => {
}
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -21,6 +21,6 @@ export const post: RequestHandler = async (event) => {
await db.updatePlausibleAnalyticsService({ id, fqdn, name, email, username });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,9 +4,15 @@ import { promises as fs } from 'fs';
import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
import { letsEncrypt } from '$lib/letsencrypt';
import { configureSimpleServiceProxyOn, reloadHaproxy } from '$lib/haproxy';
import {
checkHAProxy,
configureSimpleServiceProxyOn,
reloadHaproxy,
setWwwRedirection
} from '$lib/haproxy';
import { getDomain } from '$lib/components/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { makeLabelForServices } from '$lib/buildPacks/common';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -15,6 +21,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params;
try {
await checkHAProxy();
const service = await db.getService({ id, teamId });
const {
type,
@@ -76,7 +83,6 @@ export const post: RequestHandler = async (event) => {
const network = destinationDockerId && destinationDocker.network;
const host = getEngine(destinationDocker.engine);
const engine = destinationDocker.engine;
// const labels = await makeLabelForPlausibleAnalytics({ id, })
const { workdir } = await createDirectories({ repository: type, buildId: id });
@@ -132,7 +138,8 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`;
environment: config.plausibleAnalytics.environmentVariables,
volumes: [config.postgresql.volume],
restart: 'always',
depends_on: [`${id}-postgresql`, `${id}-clickhouse`]
depends_on: [`${id}-postgresql`, `${id}-clickhouse`],
labels: makeLabelForServices('plausibleAnalytics')
},
[`${id}-postgresql`]: {
container_name: `${id}-postgresql`,
@@ -185,11 +192,12 @@ COPY ./init-db.sh /docker-entrypoint-initdb.d/init-db.sh`;
if (isHttps) {
await letsEncrypt({ domain, id });
}
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,7 +1,7 @@
import { getUserDetails, removeDestinationDocker } from '$lib/common';
import { getDomain } from '$lib/components/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -37,13 +37,17 @@ export const post: RequestHandler = async (event) => {
console.error(error);
}
await configureSimpleServiceProxyOff({ domain });
try {
await configureSimpleServiceProxyOff({ domain });
} catch (error) {
console.log(error);
}
}
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -15,6 +15,6 @@ export const post: RequestHandler = async (event) => {
await db.updateVaultWardenService({ id, fqdn, name });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,9 +4,15 @@ import { promises as fs } from 'fs';
import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
import { letsEncrypt } from '$lib/letsencrypt';
import { configureSimpleServiceProxyOn, reloadHaproxy } from '$lib/haproxy';
import {
checkHAProxy,
configureSimpleServiceProxyOn,
reloadHaproxy,
setWwwRedirection
} from '$lib/haproxy';
import { getDomain } from '$lib/components/common';
import { getServiceImage, PrismaErrorHandler } from '$lib/database';
import { getServiceImage, ErrorHandler } from '$lib/database';
import { makeLabelForServices } from '$lib/buildPacks/common';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -15,6 +21,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params;
try {
await checkHAProxy();
const service = await db.getService({ id, teamId });
const { type, version, fqdn, destinationDockerId, destinationDocker } = service;
@@ -40,7 +47,8 @@ export const post: RequestHandler = async (event) => {
image: config.image,
networks: [network],
volumes: [config.volume],
restart: 'always'
restart: 'always',
labels: makeLabelForServices('vaultWarden')
}
},
networks: {
@@ -70,14 +78,15 @@ export const post: RequestHandler = async (event) => {
if (isHttps) {
await letsEncrypt({ domain, id });
}
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,7 +1,7 @@
import { getUserDetails, removeDestinationDocker } from '$lib/common';
import { getDomain } from '$lib/components/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { dockerInstance } from '$lib/docker';
import { checkContainer, configureSimpleServiceProxyOff } from '$lib/haproxy';
import type { RequestHandler } from '@sveltejs/kit';
@@ -27,13 +27,17 @@ export const post: RequestHandler = async (event) => {
} catch (error) {
console.error(error);
}
await configureSimpleServiceProxyOff({ domain });
try {
await configureSimpleServiceProxyOff({ domain });
} catch (error) {
console.log(error);
}
}
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -1,6 +1,6 @@
import { getUserDetails } from '$lib/common';
import * as db from '$lib/database';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import type { RequestHandler } from '@sveltejs/kit';
export const post: RequestHandler = async (event) => {
@@ -16,6 +16,6 @@ export const post: RequestHandler = async (event) => {
await db.updateVsCodeServer({ id, fqdn, name });
return { status: 201 };
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

View File

@@ -4,9 +4,15 @@ import { promises as fs } from 'fs';
import yaml from 'js-yaml';
import type { RequestHandler } from '@sveltejs/kit';
import { letsEncrypt } from '$lib/letsencrypt';
import { configureSimpleServiceProxyOn, reloadHaproxy } from '$lib/haproxy';
import {
checkHAProxy,
configureSimpleServiceProxyOn,
reloadHaproxy,
setWwwRedirection
} from '$lib/haproxy';
import { getDomain } from '$lib/components/common';
import { PrismaErrorHandler } from '$lib/database';
import { ErrorHandler } from '$lib/database';
import { makeLabelForServices } from '$lib/buildPacks/common';
export const post: RequestHandler = async (event) => {
const { teamId, status, body } = await getUserDetails(event);
@@ -15,6 +21,7 @@ export const post: RequestHandler = async (event) => {
const { id } = event.params;
try {
await checkHAProxy();
const service = await db.getService({ id, teamId });
const {
type,
@@ -48,7 +55,8 @@ export const post: RequestHandler = async (event) => {
environment: config.environmentVariables,
networks: [network],
volumes: [config.volume],
restart: 'always'
restart: 'always',
labels: makeLabelForServices('vscodeServer')
}
},
networks: {
@@ -80,14 +88,15 @@ export const post: RequestHandler = async (event) => {
if (isHttps) {
await letsEncrypt({ domain, id });
}
await setWwwRedirection(fqdn);
await reloadHaproxy(destinationDocker.engine);
return {
status: 200
};
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
} catch (error) {
return PrismaErrorHandler(error);
return ErrorHandler(error);
}
};

Some files were not shown because too many files have changed in this diff Show More