Compare commits

...

621 Commits

Author SHA1 Message Date
Andras Bacsai
9481beb61f Merge pull request #355 from coollabsio/next
v2.4.10
2022-04-17 20:37:56 +02:00
Andras Bacsai
141f2481a7 fix: Change user's id in sftp wp instance 2022-04-17 20:22:42 +02:00
Andras Bacsai
ea18f25adc ui: show extraconfig if wp is running 2022-04-17 20:22:21 +02:00
Andras Bacsai
9018184747 fix: Stop sFTP connection on wp stop 2022-04-17 20:22:07 +02:00
Andras Bacsai
4fc2dd55f5 chore: version++ 2022-04-17 19:17:20 +02:00
Andras Bacsai
5ef9a282eb fix: Wordpress extra config 2022-04-17 19:17:12 +02:00
Andras Bacsai
56b9a376bd fix: use redis-alpine 2022-04-14 23:48:52 +02:00
Andras Bacsai
0a1d31a188 Merge pull request #349 from coollabsio/v2.4.9
fix: Switch from bitnami/redis to normal redis
2022-04-14 23:42:13 +02:00
Andras Bacsai
64c9fb9a1b fix: Switch from bitnami/redis to normal redis 2022-04-14 23:40:23 +02:00
Andras Bacsai
47aad15cd5 Merge pull request #347 from coollabsio/v2.4.9
v2.4.9
2022-04-14 23:29:15 +02:00
Andras Bacsai
260a47a366 fix: Id of service container 2022-04-14 23:11:24 +02:00
Andras Bacsai
fd4bbe17f0 fix: Restart local docker coolify proxy in case of something happens to it 2022-04-14 21:43:22 +02:00
Andras Bacsai
25ff637703 fix: Remove proxy container in case of dependent container is down 2022-04-14 21:43:05 +02:00
Andras Bacsai
f571453696 fix: Better performance for cleanup images 2022-04-14 18:45:42 +02:00
Andras Bacsai
5cd7533972 fix: Loading of new destinations 2022-04-14 18:34:43 +02:00
Andras Bacsai
3a252509d0 fix: Add HTTP proxy checks 2022-04-14 15:04:18 +02:00
Andras Bacsai
2bd3802a6f fix: Improved tcp proxy monitoring for databases/ftp 2022-04-14 00:04:46 +02:00
Andras Bacsai
ce2757f514 fix: Teams view 2022-04-13 21:06:22 +02:00
Andras Bacsai
8419cdf604 fix: Postgres root pw is pw field 2022-04-13 19:59:30 +02:00
Andras Bacsai
907c2414ae chore:version++ 2022-04-13 19:52:56 +02:00
Andras Bacsai
f82207564f Merge pull request #344 from coollabsio/v2.4.8
v2.4.8
2022-04-13 19:19:04 +02:00
Andras Bacsai
991a09838c chore: version++ 2022-04-13 16:08:40 +02:00
Andras Bacsai
25df4bfd85 fix: Remove system wide pw reset 2022-04-13 16:05:26 +02:00
Andras Bacsai
d2f89d001b fix: GitLab typo 2022-04-13 16:05:08 +02:00
Andras Bacsai
1971f227fd fix: Register should happen if coolify proxy cannot be started 2022-04-13 14:23:42 +02:00
Andras Bacsai
c1adffe260 Merge pull request #343 from coollabsio/v2.4.7
v2.4.7
2022-04-13 13:12:35 +02:00
Andras Bacsai
e725887a55 chore:version++ 2022-04-13 13:12:23 +02:00
Andras Bacsai
5bf79b75b0 fix: Destinations to HAProxy 2022-04-13 13:10:04 +02:00
Andras Bacsai
6926975e40 Merge pull request #341 from coollabsio/v2.4.6
v2.4.6
2022-04-13 08:40:10 +02:00
Andras Bacsai
978a01c968 fix: Reverting postgres password for now 2022-04-13 08:35:20 +02:00
Andras Bacsai
f421f5ee84 fix: No permission on first registration 2022-04-12 23:57:08 +02:00
Andras Bacsai
383831c7b8 fix: Restart policy for resources 2022-04-12 23:12:09 +02:00
Andras Bacsai
41329facf7 fix: Try catch me 2022-04-12 22:49:48 +02:00
Andras Bacsai
7d3c644148 fix: DNS check before creating SSL cert 2022-04-12 22:18:54 +02:00
Andras Bacsai
7fab9b5930 fix: ProjectID for Github 2022-04-12 22:18:43 +02:00
Andras Bacsai
58763ef84c fix: Load all branches, not just the first 30 2022-04-12 21:48:50 +02:00
Andras Bacsai
0e6abf172b fix: Meilisearch service 2022-04-12 21:09:38 +02:00
Andras Bacsai
9e681ece41 chore: version++ 2022-04-12 20:58:02 +02:00
Andras Bacsai
28f87a306d fix: Cleanup images older than a day 2022-04-12 20:57:49 +02:00
Andras Bacsai
23e8833208 Merge pull request #339 from coollabsio/v2.4.5
v2.4.5
2022-04-12 19:08:46 +02:00
Andras Bacsai
03962663c2 fix: Timeout values 2022-04-12 18:21:10 +02:00
Andras Bacsai
cc2ec55c4d chore: version++ 2022-04-12 16:50:13 +02:00
Andras Bacsai
ff2c38aa16 fix: Invitations 2022-04-12 16:49:59 +02:00
Andras Bacsai
b5a9a2cea8 fix: Types 2022-04-12 16:49:52 +02:00
Andras Bacsai
cd3f661f7e Merge pull request #336 from coollabsio/v2.4.4
v2.4.4
2022-04-12 11:02:35 +02:00
Andras Bacsai
41bf6b5b86 fixes 2022-04-12 10:47:53 +02:00
Andras Bacsai
a4e7c85184 Add only amd release 2022-04-12 10:14:18 +02:00
Andras Bacsai
19aca9ab35 chore: version++ 2022-04-12 10:13:19 +02:00
Andras Bacsai
08704c289a fix: Proxy 2022-04-12 10:12:46 +02:00
Andras Bacsai
2224c22c6e fix: haproxy build stuffs 2022-04-12 09:22:27 +02:00
Andras Bacsai
b281889acd Merge branch 'main' of github.com:coollabsio/coolify into main 2022-04-12 09:20:12 +02:00
Andras Bacsai
cfc50a27b0 Package.json update 2022-04-12 09:19:48 +02:00
Andras Bacsai
ed5f21da6a Merge pull request #335 from coollabsio/arm
v2.4.3 - ARM!
2022-04-12 09:10:57 +02:00
Andras Bacsai
78f3eb81dd Merge pull request #314 from Mobilpadde/fix-coloured-tooltips
Tooltip with corresponding colours
2022-04-12 07:57:09 +02:00
Andras Bacsai
6a833934ce Merge pull request #293 from dominicbachmann/improve-typing
Started to introduce more typing
2022-04-11 22:40:47 +02:00
Andras Bacsai
45bf6f77d1 Merge branch 'arm' into improve-typing 2022-04-11 22:39:45 +02:00
Andras Bacsai
a1b3b7b687 Merge branch 'arm' of github.com:coollabsio/coolify into arm 2022-04-11 22:31:32 +02:00
Andras Bacsai
7ebcad6abb fix: Update dockerfile 2022-04-11 22:31:27 +02:00
Andras Bacsai
fed6d2bf07 Merge pull request #301 from esdete2/main
Rearrange ARGs in Docker build pack
2022-04-11 22:31:16 +02:00
Andras Bacsai
bea4943e9f chore: update build packages 2022-04-11 20:43:19 +02:00
Andras Bacsai
1979e431b8 chore: update build scripts 2022-04-11 20:40:06 +02:00
Andras Bacsai
9bead1d6b4 chore: Version++ 2022-04-11 20:36:46 +02:00
Andras Bacsai
56c4295e16 chore: Update packages 2022-04-11 20:36:15 +02:00
Andras Bacsai
7c7b5a61e5 fix: Remove unnecessary save button haha 2022-04-11 20:36:03 +02:00
Andras Bacsai
abaa13fda8 Merge branch 'main' into arm 2022-04-11 20:29:29 +02:00
esdete
042bfeddbb Merge branch 'main' into main 2022-04-11 17:47:50 +02:00
Mads Bram Cordes
f45ab067ce Add fuchsia for IAM 2022-04-11 16:58:00 +02:00
Mads Bram Cordes
97a6f04aaa Merge branch 'main' into fix-coloured-tooltips 2022-04-11 16:55:37 +02:00
Andras Bacsai
417c01d6e0 Merge pull request #331 from coollabsio/v2.4.2
v2.4.2
2022-04-10 00:44:22 +02:00
Andras Bacsai
b2e7435d0f chore: version++ 2022-04-10 00:40:12 +02:00
Andras Bacsai
73c9cb1d51 Revert source configuration changes 2022-04-10 00:39:50 +02:00
Andras Bacsai
41c5dd3b53 fix: Show config missing on sources 2022-04-10 00:36:42 +02:00
Andras Bacsai
bb0c93dc2f fix: Return own and other sources better 2022-04-10 00:31:10 +02:00
Andras Bacsai
7953c1df30 fix: Missing install repositories GitHub 2022-04-10 00:30:47 +02:00
esdete
c3f4245164 Merge branch 'main' into main 2022-04-09 15:44:13 +02:00
Andras Bacsai
369001febb Merge pull request #326 from coollabsio/v2.4.1
v2.4.1
2022-04-09 14:17:48 +02:00
Andras Bacsai
7ec296be6b fix: DB Connecting string generator 2022-04-09 13:58:13 +02:00
Andras Bacsai
d2f5a58f3b fix: Able to change postgres user password from ui 2022-04-09 13:33:23 +02:00
Andras Bacsai
f4315144af chore: version++ 2022-04-09 13:26:08 +02:00
Andras Bacsai
e92775887d fix: Postgres root passwor shown and set 2022-04-09 13:26:00 +02:00
Andras Bacsai
a5f1b4b675 fix: Enable https for Ghost 2022-04-09 13:25:46 +02:00
esdete
157e5fd7aa Merge branch 'main' into main 2022-04-08 20:07:43 +02:00
Andras Bacsai
5e7e1c11c7 Merge pull request #307 from coollabsio/v2.4.0
v2.4.0
2022-04-08 15:20:34 +02:00
Andras Bacsai
e8516bc831 ui: fixes 2022-04-08 15:12:10 +02:00
Andras Bacsai
e3f78a1cf9 ui: fixes 2022-04-08 15:02:48 +02:00
Andras Bacsai
3449e0f8fc ui: fix 2022-04-08 14:16:14 +02:00
Andras Bacsai
66af12f9b5 ui: fixes 2022-04-08 14:12:06 +02:00
Andras Bacsai
13acf09dcc ui: fixes 2022-04-08 14:03:21 +02:00
Andras Bacsai
ce71dccbc1 fix: Missing buildpack 2022-04-08 11:19:01 +02:00
Andras Bacsai
d9ba1a0b5c fix: typo 2022-04-08 11:16:07 +02:00
Andras Bacsai
0b709c93a8 fix: html/apiUrls cannot end with / 2022-04-08 10:57:44 +02:00
Andras Bacsai
1657e5a151 fix: no line during buildLog 2022-04-08 10:54:40 +02:00
Andras Bacsai
a165b21950 ui: fix 2022-04-08 10:47:01 +02:00
Andras Bacsai
0d0715a340 ui/fix: Insane amount 2022-04-08 10:35:16 +02:00
Andras Bacsai
76754ded79 docs: Contribution guide 2022-04-08 00:28:10 +02:00
Andras Bacsai
4da27a46a2 fix: self-hosted GitLab URL 2022-04-08 00:16:10 +02:00
Mads Bram Cordes
039953588e Add tooltip colours to correspond with colour of Icon 2022-04-08 00:11:30 +02:00
Andras Bacsai
b8b4f559db fix: Unique storage paths 2022-04-08 00:09:09 +02:00
Andras Bacsai
2b0df270df fix: small typo 2022-04-07 23:58:56 +02:00
Andras Bacsai
b96c1a23ec fix: Ton of updates for users/teams 2022-04-07 23:26:06 +02:00
Andras Bacsai
f779b3bb54 fix: fix for the fix that fixes the fix 2022-04-07 21:29:45 +02:00
Andras Bacsai
6462982d12 fix: www or not-www, that's the question 2022-04-07 21:24:05 +02:00
Andras Bacsai
84b4cc5d54 fix: Last commit 2022-04-07 21:18:36 +02:00
Andras Bacsai
1bd2ccbc16 fix: Possible fix for spikes in CPU usage 2022-04-07 21:12:41 +02:00
Andras Bacsai
3abe1610bf fix: Do not trigger >1 webhooks on GitLab 2022-04-07 20:37:08 +02:00
Andras Bacsai
61716738ed ui: fix 2022-04-07 19:17:03 +02:00
Andras Bacsai
4e819f6eba ui: fix 2022-04-07 19:11:58 +02:00
Andras Bacsai
fedb38f2bc ui: fix 2022-04-07 18:51:52 +02:00
Andras Bacsai
aae108032c ui:fix 2022-04-07 18:45:21 +02:00
Andras Bacsai
020013683b ui: fix 2022-04-07 16:02:02 +02:00
Andras Bacsai
70de2538e2 ui: fix 2022-04-07 16:01:14 +02:00
Andras Bacsai
9f581c82a9 ui: fix 2022-04-07 15:59:01 +02:00
Andras Bacsai
eb2e07afc5 ui: fixes 2022-04-07 15:50:57 +02:00
Andras Bacsai
9c47b8495c ui: fix 2022-04-07 15:40:32 +02:00
Andras Bacsai
2f8d0ee60c ui: Better layout for root team 2022-04-07 15:23:32 +02:00
Andras Bacsai
5bf14f4639 feat: Able to modify database passwords 2022-04-07 14:29:40 +02:00
dominicbachmann
9da08d600b Merged v2.4.0 2022-04-07 01:03:13 +02:00
Andras Bacsai
4d47eab07c fix: Team view for root team 2022-04-06 22:34:56 +02:00
Andras Bacsai
f2061c5c25 fix: Only show proxy for admin team 2022-04-06 22:28:03 +02:00
Andras Bacsai
430fc66ed7 fix: Updated db versions 2022-04-06 22:15:13 +02:00
Andras Bacsai
bcb84b8126 Revert "fix: Do not pull latest image"
This reverts commit dd83e86bc3.
2022-04-06 22:10:48 +02:00
Andras Bacsai
dd83e86bc3 fix: Do not pull latest image 2022-04-06 22:06:14 +02:00
Andras Bacsai
3e8a8364dc feat: Basic white labeled version 2022-04-06 22:01:41 +02:00
dominicbachmann
be41c0dd02 Added types for store 2022-04-06 21:51:19 +02:00
dominicbachmann
a17b7a564e Added types for form 2022-04-06 21:49:43 +02:00
Andras Bacsai
f3cdda29bc code improvement 2022-04-06 21:37:42 +02:00
dominicbachmann
de37ee9f1c Added types for crypto 2022-04-06 21:10:37 +02:00
dominicbachmann
8212868b92 Added types for api 2022-04-06 21:09:15 +02:00
dominicbachmann
b44d8578d9 Added types for queues/sslrenewal 2022-04-06 21:05:36 +02:00
dominicbachmann
0358cf2de2 Added types for queues/ssl 2022-04-06 21:05:12 +02:00
dominicbachmann
94da008a47 Added types for queues/proxy 2022-04-06 21:04:51 +02:00
dominicbachmann
456b1b8074 Added types for queues/logger 2022-04-06 21:04:14 +02:00
dominicbachmann
78e6a7d1d3 Improved code quality of queues/index 2022-04-06 21:03:20 +02:00
dominicbachmann
76dc7ffb68 Added types for queues/cleanup 2022-04-06 21:01:47 +02:00
dominicbachmann
211aff7170 Added types for letsencrypt/index 2022-04-06 20:52:46 +02:00
dominicbachmann
bcacefb841 Added types for importers/gitlab 2022-04-06 20:50:57 +02:00
dominicbachmann
4505ad37d8 Added types for importers/github 2022-04-06 20:50:04 +02:00
dominicbachmann
18cf57f33c Added types for haproxy/index 2022-04-06 20:47:22 +02:00
Andras Bacsai
9f2f5b40c3 Only show teams for root team 2022-04-06 20:44:24 +02:00
dominicbachmann
8a401f50cb Added types for haproxy/configuration 2022-04-06 20:40:25 +02:00
dominicbachmann
51a5b3b602 Added types to database/users 2022-04-06 20:36:51 +02:00
dominicbachmann
68f9bca054 Added types to database/teams 2022-04-06 20:34:22 +02:00
dominicbachmann
e9e92c6e9e Added types to databse/settings 2022-04-06 20:31:51 +02:00
dominicbachmann
008cfdba09 Added types to database/services 2022-04-06 20:30:29 +02:00
dominicbachmann
9973197fa5 Added types for database/secrets 2022-04-06 20:23:27 +02:00
dominicbachmann
ec3b94cf96 added types for database/logs 2022-04-06 20:16:21 +02:00
dominicbachmann
c4cb92c78d Added types for database/gitSource 2022-04-06 20:15:15 +02:00
dominicbachmann
c390f82246 Added types to database/gitlab 2022-04-06 20:01:35 +02:00
dominicbachmann
b4f98e24a1 Added types to database/github 2022-04-06 19:56:47 +02:00
dominicbachmann
e042c5cfde Added types for database/databases 2022-04-06 19:45:47 +02:00
dominicbachmann
faeae8fd6c Added typings for database/destinations 2022-04-06 19:34:17 +02:00
Andras Bacsai
ae4942ba29 feat: Able to change service version/tag 2022-04-06 19:17:28 +02:00
Philip Schmidt
fd652bfce6 write args at the beginning of dockerfile and inherit them for each stage 2022-04-06 18:33:02 +02:00
Andras Bacsai
3d72167721 Merge branch 'v2.4.0' of github.com:coollabsio/coolify into v2.4.0 2022-04-06 17:21:32 +02:00
Andras Bacsai
ba284bef9e Merge pull request #292 from Soneji/patch-1
Add plausible/analytics:stable docker tag
2022-04-06 17:20:50 +02:00
Andras Bacsai
d18bb9cc74 Extend typings 2022-04-06 17:18:25 +02:00
Andras Bacsai
a7ed3e58db Merge pull request #287 from dominicbachmann/dockerfile-typing
Implemented typing for dockerfile configuration
2022-04-06 17:12:17 +02:00
Andras Bacsai
8405ebd28d feat: Admin team sees everything 2022-04-06 15:55:17 +02:00
Andras Bacsai
352bb65125 ui: fix 2022-04-06 14:57:41 +02:00
Andras Bacsai
fe2cc5a99a feat: Working on-demand sftp to wp data 2022-04-06 14:27:51 +02:00
Andras Bacsai
7a2f29f6a3 feat: PHP Composer support 2022-04-06 13:35:53 +02:00
Andras Bacsai
9a05bfa899 fix: Fix for fix haha 2022-04-06 10:30:53 +02:00
Andras Bacsai
39fa64e20d fix: On-demand sFTP for wp 2022-04-06 10:29:42 +02:00
Andras Bacsai
3a835b420e WIP 2022-04-05 23:44:18 +02:00
dominicbachmann
82f7633c3a Improved typing and quality of database/checks and database/common code 2022-04-05 21:15:02 +02:00
dominicbachmann
9fdac2741a Improved typing and quality of applications.ts 2022-04-05 20:48:33 +02:00
dominicbachmann
8fb5260809 Resolved merge conflicts 2022-04-05 20:17:53 +02:00
dominicbachmann
e08ec12d26 Introduced typing for the buildJob and cleaned up common.ts 2022-04-05 20:11:19 +02:00
Dominic Bachmann
1202e00a21 Merge branch 'main' into dockerfile-typing 2022-04-05 19:36:52 +02:00
Andras Bacsai
4ba2205af4 fix: Permission issues 2022-04-05 17:37:03 +02:00
Andras Bacsai
09841ad4cb fix: Add openssl to image 2022-04-05 17:21:40 +02:00
Andras Bacsai
d2dcd0abc8 chore:version++ 2022-04-05 17:15:21 +02:00
Andras Bacsai
fe9d0503fb feat: Finalize on-demand sftp for wp 2022-04-05 17:15:06 +02:00
Andras Bacsai
8e9e6607e5 feat: Wordpress on-demand SFTP 2022-04-05 15:56:25 +02:00
Dhaval Soneji
e1efd9355f Add plausible/analytics:stable docker tag 2022-04-05 14:03:36 +01:00
Andras Bacsai
ca705bbf89 Merge pull request #290 from coollabsio/v2.3.3
v2.3.3
2022-04-05 11:19:07 +02:00
Andras Bacsai
b70fe09d17 fix: Remove asyncUntil 2022-04-05 11:13:13 +02:00
Andras Bacsai
d7d570393f Revert try 2022-04-05 11:09:17 +02:00
Andras Bacsai
41ca265e5a Try to not restart redis? 2022-04-05 11:00:36 +02:00
Andras Bacsai
03cde08d67 fix: Lame fixing 2022-04-05 10:58:47 +02:00
Andras Bacsai
5684674bd7 fix: revert seed 2022-04-05 10:36:28 +02:00
Andras Bacsai
4fe919f2ea Merge branch 'v2.3.3' of github.com:coollabsio/coolify into v2.3.3 2022-04-05 10:36:12 +02:00
Andras Bacsai
c8c23c53ef fix: Update stucked builds 2022-04-05 10:36:09 +02:00
Andras Bacsai
b1c25e98d7 fix: Update stucked builds on startup 2022-04-05 10:34:31 +02:00
Andras Bacsai
7ab5a4bfcf fix: Try to update build status several times 2022-04-05 10:30:18 +02:00
Andras Bacsai
a3ee57995c chore: Version++ 2022-04-05 10:21:46 +02:00
Andras Bacsai
32020fd336 fix: Add git lfs while deploying 2022-04-05 10:21:40 +02:00
dominicbachmann
f1313b6468 Implemented typing for dockerfile configuration 2022-04-05 01:13:25 +02:00
Andras Bacsai
3ef093c7e6 Merge pull request #286 from coollabsio/v2.3.2
v2.3.2
2022-04-04 19:40:39 +02:00
Andras Bacsai
f5dfaa81d3 chore:version++ 2022-04-04 19:35:17 +02:00
Andras Bacsai
fcf206a081 fix: Add default webhook domain for n8n 2022-04-04 19:18:06 +02:00
Andras Bacsai
9790d2b613 fix(php): If .htaccess file found use apache 2022-04-04 18:47:22 +02:00
Andras Bacsai
201fa82efc Merge pull request #284 from coollabsio/v2.3.1
v2.3.1
2022-04-04 14:00:28 +02:00
Andras Bacsai
d28433ee64 fix: Default configuration 2022-04-04 13:55:11 +02:00
Andras Bacsai
cc348bf0f5 chore: Version++ 2022-04-04 13:49:37 +02:00
Andras Bacsai
b023d65fcf fix: Secrets build/runtime coudl be changed after save 2022-04-04 13:49:26 +02:00
Andras Bacsai
305fab488e Merge pull request #276 from coollabsio/v2.3.0
v2.3.0
2022-04-04 11:30:19 +02:00
Andras Bacsai
38f0546f05 fix: Gitlab & Github urls 2022-04-04 11:27:23 +02:00
Andras Bacsai
8cb679711d fix: UI 2022-04-04 11:08:32 +02:00
Andras Bacsai
4d11867500 Merge branch 'main' of github.com:coollabsio/coolify into v2.3.0 2022-04-04 10:41:50 +02:00
Andras Bacsai
8232a7468b fix: Build log 2022-04-03 23:34:17 +02:00
Andras Bacsai
03e7af12be fix: Remove console.log 2022-04-03 23:03:41 +02:00
Andras Bacsai
39f2e28a11 fix: Async progress 2022-04-03 22:53:50 +02:00
Andras Bacsai
53947d805b fix: Lets await! 2022-04-03 22:53:11 +02:00
Andras Bacsai
15f8e44237 Merge pull request #281 from dominicbachmann/fix-husky-pre-commit
Changed the package manager used in the .husky/pre-commit hook
2022-04-03 22:32:36 +02:00
Andras Bacsai
5ce1bc1ec5 Merge pull request #282 from dominicbachmann/fix-contributing-guide
Fixed contributing guide
2022-04-03 22:32:20 +02:00
Andras Bacsai
c36bd34a1a fix: Small UI fix on logs 2022-04-03 22:31:07 +02:00
Andras Bacsai
781d034484 fix: Build log fix attempt #1 2022-04-03 22:18:04 +02:00
Andras Bacsai
5160d0780e fix: No need to paste clear text env for previews 2022-04-03 21:38:58 +02:00
dominicbachmann
b8b57bc48b Fixed contributing guide 2022-04-03 19:15:26 +02:00
dominicbachmann
58406f055e Changed the package manager used in the .husky/pre-commit hook from yarn to pnpm 2022-04-03 19:10:29 +02:00
Andras Bacsai
b049297082 fix: Infinite loop on www domains 2022-04-03 17:49:41 +02:00
Andras Bacsai
45af5cbef8 fix: Rename envs to secrets 2022-04-03 00:03:51 +02:00
Andras Bacsai
463dacbe59 chore: Lock file + fix packages 2022-04-02 23:58:59 +02:00
Andras Bacsai
01e0fb70c9 Merge branch 'v2.3.0' of github.com:coollabsio/coolify into v2.3.0 2022-04-02 23:53:41 +02:00
Andras Bacsai
6ac54e17f4 Merge pull request #277 from SaraVieira/allow-paste-env
feat: Add ability to paste env files
2022-04-02 23:52:53 +02:00
Andras Bacsai
a82805846f fix: If user not found 2022-04-02 23:48:56 +02:00
Sara Vieira
6309074844 clean when done 2022-04-02 23:30:16 +02:00
Sara Vieira
b80e0d15fb feat: Add abilitry to paste env files 2022-04-02 23:25:55 +02:00
Andras Bacsai
c55505af6c feat: MeiliSearch service 2022-04-02 23:08:27 +02:00
Andras Bacsai
5f27fc0770 Merge pull request #275 from SaraVieira/274-fix
Get error correctly in catch
2022-04-02 22:35:13 +02:00
Sara Vieira
b814c6e563 get error correctly; closes 274 2022-04-02 22:21:22 +02:00
Andras Bacsai
7a74ba1796 ui: Improvements 2022-04-02 17:43:24 +02:00
Andras Bacsai
066f5b25e0 fix: Python no wsgi 2022-04-02 17:05:32 +02:00
Andras Bacsai
18f7ab1b95 Merge pull request #268 from restray/main
feat(dev): allow windows users to use pnpm dev
2022-04-02 16:28:44 +02:00
Andras Bacsai
78293340cc chore: version++ 2022-04-02 16:27:44 +02:00
Andras Bacsai
c47457a17f Merge pull request #269 from restray/restray_registre_loading
feat(auth): add loading on register button
2022-04-02 16:26:57 +02:00
Andras Bacsai
d00629b627 Merge pull request #273 from Just-Moh-it/patch-1
Suggested change
2022-04-02 16:26:02 +02:00
Andras Bacsai
ddfbda6f80 feat: initial python support 2022-04-02 16:22:51 +02:00
Andras Bacsai
b60b832426 chore: version++ 2022-04-02 15:53:25 +02:00
Mohit Yadav
adfc976f41 Suggested change
Changed to appropriate word
2022-04-02 17:28:42 +05:30
Andras Bacsai
1b43976ff0 Update proxy build commands 2022-04-02 13:39:24 +02:00
Andras Bacsai
321fb019eb Update dockerfiles for arm 2022-04-01 23:02:23 +02:00
Andras Bacsai
f6858a68e0 Update schema 2022-04-01 22:51:08 +02:00
Restray
809f40dec9 feat: add loading on register button 2022-04-01 21:41:22 +02:00
Restray
f3b5de4697 feat(dev): allow windows users to use pnpm dev 2022-04-01 21:10:24 +02:00
Andras Bacsai
fe17e2eaba Prisma Engine build script 2022-04-01 17:57:37 +02:00
Andras Bacsai
22ef0b5d29 Update packages 2022-04-01 17:46:08 +02:00
Andras Bacsai
823279fb60 Updates 2022-04-01 17:16:11 +02:00
Andras Bacsai
19f661706d fix: Ignore coolify proxy error for now 2022-04-01 15:34:29 +02:00
Andras Bacsai
986c5b7133 Merge pull request #264 from coollabsio/v2.2.7
v2.2.7
2022-04-01 14:43:53 +02:00
Andras Bacsai
4e334d4fff fix: Use NodeJS for sveltekit for now 2022-04-01 14:41:38 +02:00
Andras Bacsai
dcf7f92aab fix: Build variables 2022-04-01 14:29:06 +02:00
Andras Bacsai
f56361c0ca updates for ARM 2022-04-01 14:25:55 +02:00
Andras Bacsai
4946ca2d91 Dockerfile for multiarch builds 2022-04-01 00:08:29 +02:00
Andras Bacsai
f6a91cb53c fix: Haproxy errors 2022-04-01 00:07:29 +02:00
Andras Bacsai
726fbbb52a Merge pull request #257 from coollabsio/v2.2.6
v2.2.6
2022-03-31 20:57:34 +02:00
Andras Bacsai
29d2278579 fix: Add PROTO headers 2022-03-31 20:55:58 +02:00
Andras Bacsai
72ceeff022 Merge pull request #255 from coollabsio/v2.2.5
v2.2.5
2022-03-31 17:47:46 +02:00
Andras Bacsai
54d65ec011 chore: Version++ 2022-03-31 17:45:20 +02:00
Andras Bacsai
96aef5c4a6 fix: registration enabled/disabled 2022-03-31 17:45:04 +02:00
Andras Bacsai
7b64166fb0 Merge pull request #253 from coollabsio/v2.2.4
v2.2.4
2022-03-31 15:45:37 +02:00
Andras Bacsai
1f5908e0b8 fix: No need to dashify anymore 2022-03-31 15:42:15 +02:00
Andras Bacsai
a4562d18b6 chore: version++ 2022-03-31 15:41:02 +02:00
Andras Bacsai
875e232199 fix: Gitlab repo url 2022-03-31 15:40:26 +02:00
Andras Bacsai
80f95a4674 Merge pull request #244 from coollabsio/v2.2.3
v2.2.3
2022-03-31 15:17:38 +02:00
Andras Bacsai
17d56aa972 fix: Space in repo names 2022-03-31 15:11:51 +02:00
Andras Bacsai
f4ba60cf8f Merge pull request #249 from TommasoAmici/patch-1
chore: fixed typo on New Git Source view
2022-03-31 11:44:54 +02:00
Andras Bacsai
0b8a648f13 fix: Add license 2022-03-31 09:11:09 +02:00
Tommaso A
2576a3af2c chore: fixed typo on New Git Source view 2022-03-30 18:13:00 +02:00
Andras Bacsai
2e6c73fa3c chore: version++ 2022-03-30 10:12:04 +02:00
Andras Bacsai
b8d8ee4560 fix: Persistent storage on webhooks 2022-03-30 09:28:45 +02:00
Andras Bacsai
d9b74ada84 Merge pull request #239 from SaraVieira/patch-1
fix compare link in CONTRIBUTING
2022-03-28 15:35:04 +02:00
Andras Bacsai
01b058151b Merge pull request #240 from coollabsio/init-fqdn
v2.2.2
2022-03-28 15:24:37 +02:00
Andras Bacsai
989d952f35 chore: version++ 2022-03-28 15:21:03 +02:00
Andras Bacsai
908af3e024 fix: Reload window on settings saved 2022-03-28 15:20:49 +02:00
Sara Vieira
819157fda1 fix compare link in CONTRIBUTING 2022-03-28 15:04:00 +02:00
Andras Bacsai
5a4458e93f Merge pull request #237 from coollabsio/docs
v2.2.1
2022-03-28 13:35:52 +02:00
Andras Bacsai
1fbd403f34 chore: version++ 2022-03-28 13:28:09 +02:00
Andras Bacsai
098e519c55 Contribution 2022-03-28 13:26:38 +02:00
Andras Bacsai
3ef4a242f9 fix: List ghost services 2022-03-28 13:10:58 +02:00
Andras Bacsai
ad3044dce1 Merge pull request #234 from coollabsio/v2.2.0
v2.2.0
2022-03-27 22:48:04 +02:00
Andras Bacsai
e40541d831 design: Colors on svelte-select 2022-03-27 22:40:36 +02:00
Andras Bacsai
2786e7dbaf Merge pull request #235 from SaraVieira/add-better-repo-select
Add search in repo and branch select
2022-03-27 22:34:15 +02:00
Andras Bacsai
196d681a63 fix: Ghost icon, remove console.log 2022-03-27 22:32:31 +02:00
Andras Bacsai
d2353e3c35 fix: Ghost logo size 2022-03-27 22:28:39 +02:00
Andras Bacsai
2475031f88 feat: Ghost service 2022-03-27 22:03:21 +02:00
Sara Vieira
cd15e68adc remove console.log 2022-03-27 21:56:23 +02:00
Sara Vieira
27431f779d clean css 2022-03-27 21:50:28 +02:00
Sara Vieira
b9b5a2faeb add search in repo and branch select 2022-03-27 21:48:25 +02:00
Andras Bacsai
e471b11d3b Add icons 2022-03-27 14:37:32 +02:00
Andras Bacsai
a742a3d2e3 feat: Add update kuma service 2022-03-27 14:05:36 +02:00
Andras Bacsai
c615f6c07e chore: Version ++ 2022-03-27 13:49:13 +02:00
Andras Bacsai
a6ebfb08f7 feat: Add n8n.io service 2022-03-27 13:49:04 +02:00
Andras Bacsai
2b0d162226 Merge pull request #232 from coollabsio/v2.1.1
v2.1.1
2022-03-25 15:41:26 +01:00
Andras Bacsai
2c5f09a8bb fix: Cleanup only 2 hours+ old images 2022-03-25 15:34:14 +01:00
Andras Bacsai
ef073e586b Test nocheck proxy 2022-03-25 10:48:11 +01:00
Andras Bacsai
82bfdb87e3 UI fixes 2022-03-25 10:36:47 +01:00
Andras Bacsai
767e7b80cb chore: version++ 2022-03-25 09:14:55 +01:00
Andras Bacsai
8d26ea9063 Update packages 2022-03-25 09:14:32 +01:00
Andras Bacsai
1a7c4310d0 Merge pull request #230 from coollabsio/v2.1.0
v2.1.0
2022-03-23 11:54:15 +01:00
Andras Bacsai
4e8fe79e2b feat: Be able to redeploy PRs 2022-03-23 11:49:40 +01:00
Andras Bacsai
a8c5551292 fix: Volumes 2022-03-23 11:14:38 +01:00
Andras Bacsai
2bf73109b2 feat: Use compose instead of normal docker cmd 2022-03-23 10:25:32 +01:00
Andras Bacsai
f0ab3750bd Disable PHP modules, as the new image has all activated by default 2022-03-22 15:56:03 +01:00
Andras Bacsai
58a11e37fe Add schema 2022-03-22 14:58:08 +01:00
Andras Bacsai
927bf46304 fix: skip ssl cert in case of error 2022-03-22 10:37:33 +01:00
Andras Bacsai
6b89857697 chore: version++ 2022-03-22 10:24:52 +01:00
Andras Bacsai
b72e5ccef6 Merge branch 'main' into v2.0.32 2022-03-22 10:23:11 +01:00
Andras Bacsai
6617b7811b log ssl errors 2022-03-22 10:22:20 +01:00
Andras Bacsai
e1c1988db4 Merge pull request #229 from coollabsio/importer-error
Add debug for GH importer
2022-03-22 09:42:49 +01:00
Andras Bacsai
af99ea4678 Add debug for GH importer 2022-03-22 09:35:24 +01:00
Andras Bacsai
a6d5316090 WIP - Persistent storage 2022-03-21 21:46:49 +01:00
Andras Bacsai
f5e7a84fa6 Update buildpacks for static sites 2022-03-21 21:25:01 +01:00
Andras Bacsai
c013764b61 WIP Persistent storage 2022-03-21 16:58:13 +01:00
Andras Bacsai
2320ab0dfc WIP - Persistent storage 2022-03-20 23:51:50 +01:00
Andras Bacsai
1281a0f7e4 Merge pull request #226 from coollabsio/v2.0.31
v2.0.31
2022-03-20 15:21:57 +01:00
Andras Bacsai
d8350cd4ee Migration file 2022-03-20 15:14:33 +01:00
Andras Bacsai
e3b7c23ed9 chore: Version++ 2022-03-20 15:05:05 +01:00
Andras Bacsai
eae1ea21d6 fix: Add nginx + htaccess files 2022-03-20 15:03:24 +01:00
Andras Bacsai
541aa76b64 fix: Only cleanup same app 2022-03-20 14:21:11 +01:00
Andras Bacsai
7b8555d524 fix: Cleanup old builds 2022-03-20 14:20:29 +01:00
Andras Bacsai
fdf998c181 css fix for select 2022-03-20 14:03:52 +01:00
Andras Bacsai
3d6b343adc remove mysql 2022-03-19 23:47:05 +01:00
Andras Bacsai
e338cecc14 feat: Add PHP modules 2022-03-19 23:46:33 +01:00
Andras Bacsai
e5537a33fb Merge pull request #223 from coollabsio/v2.0.30
v2.0.30
2022-03-19 15:11:42 +01:00
Andras Bacsai
35384deb68 fix: Remove build logs in case of app removed 2022-03-19 15:06:25 +01:00
Andras Bacsai
547ca60c2a fix: Better queue system + more support on monorepos 2022-03-19 15:04:52 +01:00
Andras Bacsai
376f6f7455 fix: Basedir for dockerfiles 2022-03-19 13:33:31 +01:00
Andras Bacsai
abe92dedff fix: no webhook secret found? 2022-03-15 17:35:37 +01:00
Andras Bacsai
4b521ceedc chore: version++ 2022-03-15 17:25:17 +01:00
Andras Bacsai
6dfcb9e52b fix: No error if GitSource is missing 2022-03-15 17:22:28 +01:00
Andras Bacsai
335e3216e2 fix: Missing session data 2022-03-15 17:21:18 +01:00
Andras Bacsai
5b22bb4818 fix: No cookie found 2022-03-15 17:04:15 +01:00
Andras Bacsai
0097004882 Merge pull request #217 from coollabsio/v2.0.29
v2.0.29
2022-03-12 00:28:26 +01:00
Andras Bacsai
1bc9e4c2d3 fix: Autodeploy true by default for GH repos 2022-03-11 23:56:11 +01:00
Andras Bacsai
36c7e1a3c3 feat: Install pnpm into docker image if pnpm lock file is used 2022-03-11 23:55:57 +01:00
Andras Bacsai
c6b4d04e26 Revert double build 2022-03-11 22:48:55 +01:00
Andras Bacsai
fa6cf068c7 feat: Autodeploy pause 2022-03-11 22:36:21 +01:00
Andras Bacsai
7c273a3a48 feat: Check ssl for new apps/services first 2022-03-11 21:28:27 +01:00
Andras Bacsai
3de2ea1523 chore: version++ 2022-03-11 21:19:03 +01:00
Andras Bacsai
c5c9f84503 feat: Webhooks inititate all applications with the correct branch 2022-03-11 21:18:12 +01:00
Andras Bacsai
16ea9a3e07 Update options request 2022-03-11 20:52:11 +01:00
Andras Bacsai
48f952c798 fix: Personal Gitlab repos 2022-03-11 20:47:26 +01:00
Andras Bacsai
f78ea5de07 Remove colors Tailwind 2022-03-11 20:47:13 +01:00
Andras Bacsai
5adbd5e784 Merge pull request #210 from coollabsio/v2.0.28
v2.0.28
2022-03-04 15:39:35 +01:00
Andras Bacsai
5b2afa79d7 chore: version++ 2022-03-04 15:20:03 +01:00
Andras Bacsai
dc4e6d02b7 feat: Service secrets 2022-03-04 15:14:25 +01:00
Andras Bacsai
8ae61c8f78 fix: do not error if proxy is not running 2022-03-04 14:20:20 +01:00
Andras Bacsai
684b8e0914 Merge pull request #207 from coollabsio/v2.0.27
v2.0.27
2022-03-02 21:15:32 +01:00
Andras Bacsai
7c3314abae force image deletion 2022-03-02 21:14:53 +01:00
Andras Bacsai
ab9f8ff356 Before latest image 2022-03-02 21:08:36 +01:00
Andras Bacsai
892d8cd5c1 Reload proxy after ssl renewal 2022-03-02 21:04:42 +01:00
Andras Bacsai
8b8b45778d fix: application state in UI 2022-03-02 21:01:25 +01:00
Andras Bacsai
6655fb182c fix: cleanup coolify images 2022-03-02 20:57:28 +01:00
Andras Bacsai
0926d40247 fix: Reload haproxy if new cert is added 2022-03-02 20:43:16 +01:00
Andras Bacsai
ddc4d36688 Fix cleanup process of old coolify images 2022-03-02 20:32:29 +01:00
Andras Bacsai
53e1f22eb1 fix: check when a container is running 2022-03-02 20:32:18 +01:00
Andras Bacsai
3d2a34737b prevent restarting container check 2022-03-02 15:52:22 +01:00
Andras Bacsai
ebde77008c Cleanup coolify image fix 2022-03-02 15:52:06 +01:00
Andras Bacsai
3d27fd04ba cleanup old images of coolify 2022-03-02 14:53:43 +01:00
Andras Bacsai
d9fcaf3473 update packages 2022-03-02 14:53:33 +01:00
Andras Bacsai
d266f761aa Stats open with auth 2022-03-02 14:38:51 +01:00
Andras Bacsai
1d01405412 chore: Version++ 2022-03-02 13:38:58 +01:00
Andras Bacsai
7c62eb5bd6 feat: Send version with update request 2022-03-02 13:38:45 +01:00
Andras Bacsai
4dcc76d366 fix: Update process 2022-03-02 13:37:06 +01:00
Andras Bacsai
d2fad19a11 Update package.json 2022-03-02 12:23:40 +01:00
Andras Bacsai
7c92c4c964 Merge pull request #206 from coollabsio/feat/languagetool
v2.0.26
2022-03-02 12:22:44 +01:00
Andras Bacsai
5a71d33236 chore: Version++ 2022-03-02 12:20:20 +01:00
Andras Bacsai
1b4db4f793 fix 2022-03-02 12:20:02 +01:00
Andras Bacsai
c084b22815 fix: volume name 2022-03-02 12:17:48 +01:00
Andras Bacsai
acacef95cd fix: reload proxy on ssl cert 2022-03-02 12:10:12 +01:00
Andras Bacsai
5d722183d3 feat: Languagetool service 2022-03-02 11:57:03 +01:00
Andras Bacsai
ac19ea5407 Merge pull request #202 from coollabsio/fix
v2.0.24
2022-03-02 11:18:51 +01:00
Andras Bacsai
d19b05b970 fix: update process 2022-03-02 11:00:08 +01:00
Andras Bacsai
a0795136ac fix 2022-03-01 15:30:39 +01:00
Andras Bacsai
d2566e345a fix 2022-03-01 15:27:33 +01:00
Andras Bacsai
66cd7cf90e remove debug logging 2022-03-01 15:27:06 +01:00
Andras Bacsai
9a599981ef fix 2022-03-01 15:25:13 +01:00
Andras Bacsai
f51f7bc82a fix 2022-03-01 15:22:11 +01:00
Andras Bacsai
dbcbac0137 cleanup 2022-03-01 14:29:15 +01:00
Andras Bacsai
e722f8a87c fix: Reconfigure proxy on restart 2022-03-01 14:02:46 +01:00
Andras Bacsai
61679749eb fix: null proxyhash on restart 2022-03-01 13:15:23 +01:00
Andras Bacsai
23e12c9c44 fix: ssl + sslrenew 2022-03-01 13:07:34 +01:00
Andras Bacsai
6da78cd3e5 remove proxy refresh 2022-03-01 11:45:29 +01:00
Andras Bacsai
78ce8100a3 migrate file 2022-03-01 11:19:40 +01:00
Andras Bacsai
76ba338b45 fix 2022-03-01 11:17:34 +01:00
Andras Bacsai
823fe2deb2 refactor 2022-03-01 11:10:10 +01:00
Andras Bacsai
cb90f692f2 WIP proxy 2022-03-01 00:20:28 +01:00
Andras Bacsai
0325343ede save 2022-03-01 00:12:54 +01:00
Andras Bacsai
69d1556a1d WIP better automatic proxy conf 2022-03-01 00:08:54 +01:00
Andras Bacsai
2daa043840 WIP 2022-02-28 16:55:02 +01:00
Andras Bacsai
f340ca9d05 WIP 2022-02-28 16:06:44 +01:00
Andras Bacsai
02abd038fa fix: Better proxy check 2022-02-28 11:20:46 +01:00
Andras Bacsai
b9da68ec28 Merge pull request #199 from coollabsio/fixes
v2.0.23
2022-02-28 10:25:26 +01:00
Andras Bacsai
88b3910d80 fix: Cleanup old images, > 3 days 2022-02-28 10:12:04 +01:00
Andras Bacsai
160412f6e4 fix: Add coolify-image label for build images 2022-02-28 10:09:34 +01:00
Andras Bacsai
59a86b25fc UI: Application start 2022-02-28 10:00:09 +01:00
Andras Bacsai
49e58b39f5 chore: version++ 2022-02-28 09:57:36 +01:00
Andras Bacsai
58e0757bbd fix: Default npm command 2022-02-28 09:50:47 +01:00
Andras Bacsai
5ff4197572 fix: missing fqdn for services 2022-02-28 09:48:24 +01:00
Andras Bacsai
b56e28d27a UI: colorful states 2022-02-28 09:48:12 +01:00
Andras Bacsai
c3d39e1dd4 fix: Be sure .env exists 2022-02-28 09:31:36 +01:00
Andras Bacsai
716aa36bfd Merge pull request #195 from coollabsio/next
v2.0.22-fixes
2022-02-27 12:42:03 +01:00
Andras Bacsai
f01460170e Fix 2022-02-27 12:35:29 +01:00
Andras Bacsai
a414ce282d revert old update sequence 2022-02-27 12:31:39 +01:00
Andras Bacsai
6c32f3b130 fix: update version 2022-02-27 12:22:04 +01:00
Andras Bacsai
4cf907c572 fix: do not remove coolify proxy 2022-02-27 12:17:40 +01:00
Andras Bacsai
b28baaa5aa Merge pull request #193 from coollabsio/next
v2.0.22
2022-02-27 11:55:56 +01:00
Andras Bacsai
980dea64e0 fix: Fix proxy every 10 secs 2022-02-27 11:52:05 +01:00
Andras Bacsai
c340f6436f chore: Version++ 2022-02-27 11:19:03 +01:00
Andras Bacsai
54376fd105 remove remote docker for now 2022-02-27 11:14:46 +01:00
Andras Bacsai
ef006578b2 fix: Add icons for eleventy + astro 2022-02-26 22:15:22 +01:00
Andras Bacsai
b0b1ee0c60 fix: Always use a buildpack 2022-02-26 22:01:44 +01:00
Andras Bacsai
4e2026aa2d fix: Remove wrong/stuck proxy configurations 2022-02-26 22:01:24 +01:00
Andras Bacsai
e0e50b4bd5 WIP: Remote docker engine 2022-02-26 15:08:26 +01:00
Andras Bacsai
c9b52f1310 fix: Coolify image pulls 2022-02-24 10:37:37 +01:00
Andras Bacsai
0195213dfb Merge pull request #189 from coollabsio/next
v2.0.21
2022-02-24 10:17:38 +01:00
Andras Bacsai
d6225cbde3 fix: Improvement on image pulls 2022-02-24 10:11:48 +01:00
Andras Bacsai
7b4c194b97 chore: version++ 2022-02-24 09:38:11 +01:00
Andras Bacsai
a5ecff24a3 feat: Registration page 2022-02-24 09:32:34 +01:00
Andras Bacsai
c9c003dc9b fix: Docker scanner 2022-02-24 08:50:47 +01:00
Andras Bacsai
fd95936219 feat: 11ty buildpack 2022-02-24 00:30:33 +01:00
Andras Bacsai
15a3fd4456 feat: Astro buildpack 2022-02-23 22:07:06 +01:00
Andras Bacsai
df896542e4 update packages 2022-02-23 15:47:09 +01:00
Andras Bacsai
8927e81274 changes for demo 2022-02-23 13:38:43 +01:00
Andras Bacsai
340f061827 fix: http for demo, oops 2022-02-23 13:32:43 +01:00
Andras Bacsai
15cbac97c2 feat: Random domain for services 2022-02-23 13:25:57 +01:00
Andras Bacsai
bb32d0f7d1 feat: Random subdomain for demo 2022-02-23 13:20:17 +01:00
Andras Bacsai
c370fba9ba Merge pull request #185 from coollabsio/next
v2.0.20
2022-02-23 13:00:08 +01:00
Andras Bacsai
6e32421172 chore: Version++ 2022-02-23 12:58:46 +01:00
Andras Bacsai
6643687c0a fix: Revert default network 2022-02-23 12:58:32 +01:00
Andras Bacsai
ed01e78d77 improvement: dns check 2022-02-23 12:43:04 +01:00
Andras Bacsai
93aed52f88 Login page description for demo page 2022-02-23 11:14:04 +01:00
Andras Bacsai
bb6d1fd6a3 cleanup 2022-02-23 10:40:34 +01:00
Andras Bacsai
6e33179fc2 Update README.md 2022-02-23 10:40:21 +01:00
Andras Bacsai
277fd167cf Merge pull request #184 from coollabsio/next
v2.0.19
2022-02-23 10:29:10 +01:00
Andras Bacsai
98e8d5170b fix: Settings fqdn grr 2022-02-23 10:26:29 +01:00
Andras Bacsai
11ee1651ae fix: Random network name for demo 2022-02-23 10:22:25 +01:00
Andras Bacsai
0dfcf9b1e6 Merge pull request #159 from coollabsio/next
v2.0.18
2022-02-22 20:41:53 +01:00
Andras Bacsai
08f57ac5bc UI fix 2022-02-22 20:41:07 +01:00
Andras Bacsai
7095e781e9 small fixes 2022-02-22 20:37:11 +01:00
Andras Bacsai
df18b93809 Design day! 2022-02-22 12:56:58 +01:00
Andras Bacsai
0c2e028b38 Frontend for port range 2022-02-22 10:35:39 +01:00
Andras Bacsai
80cb1bc129 fix: Use normal docker-compose in dev 2022-02-22 09:54:23 +01:00
Andras Bacsai
74c1cb51f6 nothing here 2022-02-22 09:49:17 +01:00
Andras Bacsai
2e864bddf9 nothing important 2022-02-22 09:47:21 +01:00
Andras Bacsai
e60ae91b5d design: make copy/password visible 2022-02-22 09:45:00 +01:00
Andras Bacsai
d606cd86a0 feat: Ports range 2022-02-22 09:23:41 +01:00
Andras Bacsai
bc463c37f4 fix: Lowercase email everywhere 2022-02-22 08:12:45 +01:00
Andras Bacsai
76c1480903 fix: Email is lowercased in login 2022-02-22 08:10:33 +01:00
Andras Bacsai
6f312caf8b chore: Version++ 2022-02-21 12:46:37 +01:00
Andras Bacsai
980d8d374f Merge branch 'main' into next 2022-02-21 12:46:08 +01:00
Andras Bacsai
c49b34942f Merge pull request #164 from coollabsio/fix/github-token
v2.0.17
2022-02-21 12:41:36 +01:00
Andras Bacsai
fcfa8717a5 fix: Move tokens from session to cookie/store 2022-02-21 12:35:20 +01:00
Andras Bacsai
954a265965 chore: Version++ 2022-02-21 09:52:51 +01:00
Andras Bacsai
69845a020a Merge branch 'main' into fix/github-token 2022-02-21 09:51:46 +01:00
Andras Bacsai
22200fd8a7 fix: Github token 2022-02-21 09:50:15 +01:00
Andras Bacsai
add441675d feat: Public port range (WIP) 2022-02-20 15:12:01 +01:00
Andras Bacsai
d3d9754277 chore: Version ++ 2022-02-20 14:42:24 +01:00
Andras Bacsai
aa5e2edbc5 feat: Scan for lock files and set right commands 2022-02-20 14:40:15 +01:00
Andras Bacsai
310b099ecf Merge pull request #154 from coollabsio/next
v2.0.16
2022-02-20 00:48:08 +01:00
Andras Bacsai
1cfaef911c Small fixes 2022-02-20 00:17:44 +01:00
Andras Bacsai
b931c5f638 Migration file 2022-02-20 00:13:16 +01:00
Andras Bacsai
7c683668eb feat: Secrets for previews
UI: Some CSS changes
2022-02-20 00:00:31 +01:00
Andras Bacsai
cab7ac7d58 fix: If DNS not found, do not redirect 2022-02-19 22:37:45 +01:00
Andras Bacsai
15e69c538a feat: Preview secrets
chore: version++
2022-02-19 14:54:47 +01:00
Andras Bacsai
31ee938b66 Merge pull request #152 from coollabsio/next
v2.0.15
2022-02-19 14:52:35 +01:00
Andras Bacsai
e51a8d43d9 Browser 2022-02-19 14:03:33 +01:00
Andras Bacsai
64cd5b6e4b fix: Gitlab webhooks fixed 2022-02-19 13:57:56 +01:00
Andras Bacsai
6c9ef34905 chore: version++ 2022-02-18 23:25:43 +01:00
Andras Bacsai
aa89019236 fix: Database connection strings 2022-02-18 23:25:24 +01:00
Andras Bacsai
df58fcee16 Merge pull request #148 from coollabsio/next
v2.0.14
2022-02-18 22:18:42 +01:00
Andras Bacsai
ea3ffc429f fix: Plausible volume fixed 2022-02-18 22:05:02 +01:00
Andras Bacsai
2efca7a2b5 feat: Basic password reset form 2022-02-18 21:37:40 +01:00
Andras Bacsai
9db448a5e2 fix: follow icon 2022-02-18 15:51:59 +01:00
Andras Bacsai
feee90beef fix: Random port for certbot 2022-02-18 15:37:38 +01:00
Andras Bacsai
906a63b6b5 fix: ghToken in session now 2022-02-18 15:29:32 +01:00
Andras Bacsai
2ce64ac213 fix: hook.ts - relogin needed
updated packages
fix: Lots of typescript thingy
fix: ssl request flow
fix: proxy cleanup flow
2022-02-18 13:59:23 +01:00
Andras Bacsai
4d8bf57135 fix: Remove force SSL when doing let's encrypt request 2022-02-18 09:00:23 +01:00
Andras Bacsai
c5348ce4b3 fix: Minor fixes 2022-02-18 08:48:05 +01:00
Andras Bacsai
7f87c03f97 fix: Running state css 2022-02-18 00:25:15 +01:00
Andras Bacsai
9469f148ff fix: Grr 2022-02-18 00:22:17 +01:00
Andras Bacsai
ffb7dc4ec2 fix: SSL off for services 2022-02-18 00:17:07 +01:00
Andras Bacsai
242b8fa746 fix: Remove SSL with stop 2022-02-18 00:15:46 +01:00
Andras Bacsai
50cae5ac3b fix: Lets encrypt 2022-02-18 00:08:50 +01:00
Andras Bacsai
6a71233eb2 fix: Typo 2022-02-17 23:58:21 +01:00
Andras Bacsai
1aff8933c9 fix: Local docker host 2022-02-17 23:49:25 +01:00
Andras Bacsai
0ed87a5dfc fix: SSL app off 2022-02-17 23:47:37 +01:00
Andras Bacsai
24a6bcbd1e fix: Builder debug logging is better now
fix: www and non-www domain checker
2022-02-17 23:42:23 +01:00
Andras Bacsai
ca7f3da19d fix: Getport for letsencrypt
design: Add more scroll design
2022-02-17 22:56:15 +01:00
Andras Bacsai
bf047e2a3c feat: Dual certificates
desing: Lots of design/css updates
version++
2022-02-17 22:14:06 +01:00
Andras Bacsai
4454287be9 Merge branch 'main' into next 2022-02-17 10:38:47 +01:00
Andras Bacsai
3bd2183655 Merge pull request #143 from coollabsio/fix/login-quickfix
v2.0.13
2022-02-17 10:23:26 +01:00
Andras Bacsai
1f7080e8f8 fix: Login issues 2022-02-17 10:22:38 +01:00
Andras Bacsai
8b20761e8b fix: Buggy svelte-kit-cookie-session 2022-02-17 10:11:46 +01:00
Andras Bacsai
655d0b5d5f fix: Secure cookie disabled by default 2022-02-16 17:13:24 +01:00
Andras Bacsai
91849cdd3a fix www - non-www ssl 2022-02-16 00:00:49 +01:00
Andras Bacsai
df25a694c3 fix: Add no user redis to uri 2022-02-15 23:59:26 +01:00
Andras Bacsai
eabaca145e Fix 2022-02-15 23:38:10 +01:00
Andras Bacsai
2f0e458765 Expand flag for lets encrypt 2022-02-15 23:12:28 +01:00
Andras Bacsai
ff8037f231 feat: Generate www & non-www SSL certs 2022-02-15 23:02:03 +01:00
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
Andras Bacsai
004724da55 Merge pull request #119 from coollabsio/next
Unique secrets by applications
2022-02-12 15:31:53 +01:00
Andras Bacsai
97e9b5ffe3 Merge branch 'main' into next 2022-02-12 15:31:45 +01:00
Andras Bacsai
45f920f802 fix: unique secret by application
css: redesign secret page
2022-02-12 15:23:58 +01:00
Andras Bacsai
2b31532d19 Update README.md 2022-02-11 23:04:50 +01:00
Andras Bacsai
e7a6ecf95b fix: Typo 2022-02-11 21:50:47 +01:00
Andras Bacsai
545c98cee0 Merge pull request #117 from coollabsio/next
Update README.md
2022-02-11 21:50:19 +01:00
Andras Bacsai
d29ccbfe37 Update README.md 2022-02-11 21:49:30 +01:00
Andras Bacsai
d0807862e6 Merge pull request #116 from coollabsio/next
v2.0.5
2022-02-11 21:37:01 +01:00
Andras Bacsai
b92616dc14 chore: Version 2022-02-11 21:29:35 +01:00
Andras Bacsai
a1a436300d fix: Check sentry 2022-02-11 21:27:28 +01:00
Andras Bacsai
16a5aeb1ba chore: Version 2022-02-11 21:23:16 +01:00
Andras Bacsai
872095ff7a fix: Local static assets 2022-02-11 21:22:41 +01:00
Andras Bacsai
d88f2ea4c3 fix: More error handling in proxy configuration + cleanups 2022-02-11 21:14:47 +01:00
Andras Bacsai
02e0385ab8 Preserve build image as well 2022-02-11 21:07:31 +01:00
Andras Bacsai
c9751d4cd9 More images to tag 2022-02-11 21:06:48 +01:00
Andras Bacsai
162b637992 fix: Cleanup images 2022-02-11 21:04:48 +01:00
Andras Bacsai
a10ddd4063 fix: Delete all build files 2022-02-11 20:28:56 +01:00
Andras Bacsai
f46ccc63a7 Update staging release (final, I promise) 2022-02-11 15:46:17 +01:00
Andras Bacsai
fc04a45744 Update staging script (again) 2022-02-11 15:35:01 +01:00
Andras Bacsai
90c2b59a51 Update staging script 2022-02-11 15:34:45 +01:00
Andras Bacsai
d6bee99c1b update releast script 2022-02-11 15:31:53 +01:00
Andras Bacsai
0871d47568 feat: VaultWarden service 2022-02-11 15:31:25 +01:00
Andras Bacsai
5c646c1898 fix: Haproxy check should not throw error 2022-02-11 15:11:10 +01:00
Andras Bacsai
8974de165f fix: PreventDefault on a button, thats all 2022-02-11 13:43:45 +01:00
Andras Bacsai
e622294b87 feat: New update process (#115) 2022-02-11 11:46:47 +01:00
Andras Bacsai
cf9d32b556 Merge pull request #114 from coollabsio/next
fix: Docker Engine bugs
2022-02-11 09:22:28 +01:00
Andras Bacsai
e2d6b5bf64 fix: version 2022-02-11 09:13:51 +01:00
Andras Bacsai
dec58fd6d1 feat: Use tags in update 2022-02-11 09:00:45 +01:00
Andras Bacsai
dbb2241213 fix: Docker Engine bug related to live-restore and IPs 2022-02-11 08:42:47 +01:00
Andras Bacsai
3bd8ac5820 Merge pull request #112 from coollabsio/next
v2.0.3
2022-02-10 22:12:45 +01:00
Andras Bacsai
f514aa676d fix: Status is not available yet 2022-02-10 22:10:02 +01:00
Andras Bacsai
73fc9755dd fix: Only delete id.rsa in case of it exists 2022-02-10 22:06:22 +01:00
Andras Bacsai
5089c843b6 chore: Version bump 2022-02-10 21:56:44 +01:00
Andras Bacsai
cd527f2bce fix: Capture non-error as error 2022-02-10 21:56:19 +01:00
Andras Bacsai
82de234f21 fix: ENV variables set differently 2022-02-10 21:43:54 +01:00
Andras Bacsai
ae6f325c0a fix: Secrets join 2022-02-10 18:41:30 +01:00
Andras Bacsai
c64bbbe426 Update README.md 2022-02-10 15:48:16 +01:00
Andras Bacsai
eafd882a06 Update README.md 2022-02-10 15:48:03 +01:00
Andras Bacsai
460ae85226 V2 (#111)
Just v2
2022-02-10 15:47:44 +01:00
Andras Bacsai
a64b095c13 Update FUNDING.yml 2022-01-10 10:25:15 +01:00
Andras Bacsai
7ea0de3fb8 Depency bug causing errors (#80)
* bump version

* Bug causing problems in some of the dependencies
2021-08-07 13:22:17 +02:00
Andras Bacsai
b4c836afbd v1.0.23 (#68)
# Features 
- Build environment variables for NodeJS builds
- Initial monorepo support (more tests needed!)

# Fixes
- Fix wrong redirects
- Logout fix for the session manager
2021-07-16 23:42:14 +02:00
Andras Bacsai
2d0f22b379 v1.0.22 (#67) 2021-06-24 23:31:08 +02:00
Andras Bacsai
a8e9668c2b Haha 2021-06-22 12:19:12 +02:00
Andras Bacsai
425feba0e2 It's working! 2021-06-22 12:12:11 +02:00
Andras Bacsai
c09b8d888f Hmm, it should work now, right? (Please... work..) 2021-06-22 12:07:51 +02:00
Andras Bacsai
748e691a58 Hmm, ok 2021-06-22 12:02:06 +02:00
Andras Bacsai
f8c81ff95f Nooo 2021-06-22 11:54:19 +02:00
Andras Bacsai
d11c4a3cd7 Fix the fix of fix 2021-06-22 11:45:46 +02:00
Andras Bacsai
3f3ea151ef Fixes are not fixing 2021-06-22 11:40:02 +02:00
Andras Bacsai
7e2f68870c Hm, soemthing is not working 2021-06-22 11:20:21 +02:00
Andras Bacsai
df41cf14da Fix login again 2021-06-22 11:12:30 +02:00
Andras Bacsai
111370c025 Fix email login 2021-06-22 10:56:38 +02:00
Andras Bacsai
bcb2ba0b1b Fix Get Started button 2021-06-22 10:44:08 +02:00
Andras Bacsai
807d526ffa v1.0.21 (#66) 2021-06-22 10:19:20 +02:00
Andras Bacsai
2ff9c5fed5 v1.0.20 (#65) 2021-06-18 21:16:05 +02:00
Andras Bacsai
d43cd663d2 v1.0.19 (#64) 2021-06-17 20:47:09 +02:00
Andras Bacsai
dae91267e8 Corrected package.json dependencies 2021-06-16 11:14:10 +02:00
Andras Bacsai
b2d6317a23 SvelteKit package updates 2021-06-16 10:56:53 +02:00
Andras Bacsai
c49b412e69 Fix sveltekit/adapter-node version 2021-06-11 11:20:12 +02:00
Andras Bacsai
05e5d73556 v1.0.18 (#60)
* Removed nocodb image

* Quick fix for no installations
2021-06-10 11:55:02 +02:00
Andras Bacsai
53620f4b1a Update README.md 2021-06-07 23:57:31 +02:00
Andras Bacsai
9d14b03eb1 v1.0.17 (#59) 2021-06-07 23:44:36 +02:00
Andras Bacsai
04a5b1bd4f Fix for PR 2021-06-07 21:49:52 +02:00
Andras Bacsai
31b3f58b2c v1.0.16 (#51) 2021-06-07 21:33:11 +02:00
Andras Bacsai
9c173d1de0 bump version 2021-05-22 15:33:13 +02:00
Andras Bacsai
e11b6d74ed v1.0.15 (#49)
Webhook quickfix.
2021-05-22 15:28:22 +02:00
Andras Bacsai
c7efe899fa v1.0.14 (#48)
# Features
- Basic Python support

# Fixes
- Fix default start command
2021-05-22 15:18:58 +02:00
Andras Bacsai
adcd68c1ab v1.0.13 (#46) 2021-05-16 21:54:44 +02:00
Andras Bacsai
23a4ebb74a v1.0.12 - Sveltekit migration (#44)
Changed the whole tech stack to SvelteKit which means:
- Typescript 
- SSR
- No fastify :(
- Beta, but it's fine!

Other changes:
- Tailwind -> Tailwind JIT
- A lot more
2021-05-14 21:51:14 +02:00
Andras Bacsai
cccb9a5fec v1.0.11 (#41)
Features: 
- Build packs for popular frontend frameworks. It will help to understand which build packs should be chosen.

Fixes:
- Github queries optimized.
- Save repositories to store (faster navigation).
- Remove unnecessary data on dashboard requests.
- Speed up static site builds with a lot.

UI:
- Redesign of the application deployment page.
- Redesign of database deployments page.
2021-04-30 22:43:21 +02:00
Andras Bacsai
b416e3ab3e v1.0.10 (#39)
Fixes: 
- Default Nuxt port changed to 3000 (thanks to @yurgeman).
- Cleanup old images effectively.
- More attempts on container startups (3->6).
- Always clean up server logs on restart/redeploy.
2021-04-26 11:45:04 +02:00
Andras Bacsai
e16b7d65d4 Update README.md 2021-04-23 13:55:40 +02:00
Andras Bacsai
3744c64459 v1.0.9 (#37)
Features:
- Integrated the first service: [Plausible Analytics](https://plausible.io)!

Fixes:
- UI/UX fixes and new designs
2021-04-22 23:48:29 +02:00
Andras Bacsai
f742c2a3e2 Quick fix for Docker files 2021-04-19 13:08:17 +02:00
Andras Bacsai
142b83cc13 v1.0.7 (#32)
New features:
- Automatic error reporting (enabled by default)
- Increase build times by leveraging docker build caches
- 
Fixes:
- Fix error handling
- Fix vue autodetect
- Custom dockerfile is not the default

Others:
- Cleanup `logs-servers` collection, because old errors are not standardized
- New Traefik proxy version
- Standardized directory configurations
2021-04-19 09:46:05 +02:00
452 changed files with 28284 additions and 10826 deletions

View File

@@ -1,4 +1,16 @@
.DS_Store
node_modules
dist
.routify
.pnpm-store
/build
/.svelte-kit
/package
/yarn.lock
/.pnpm-store
/ssl
.env
.env.prod
.env.stag
/db/*.db
/db/*.db-journal
/data/haproxy/haproxy.cfg
/data/haproxy/haproxy.cfg.lkg

View File

@@ -1,35 +1,6 @@
####################################
# Domain where your Coolify instance will be available and reachable.
# It's the same as you set in Github OAuth App and Github App as <domain>.
DOMAIN=
## Let's Encrypt contact email required
EMAIL=
# JWT Token Sign Key for logging you in to Coolify's frontend
JWT_SIGN_KEY=
# Encryption key for SECRETS - do NOT share it with others!
SECRETS_ENCRYPTION_KEY=
# Docker Engine
DOCKER_ENGINE=/var/run/docker.sock
# Docker network to use internally between the proxy and your apps
DOCKER_NETWORK=coollabs
# Mongodb
# Values in case if you are using our Mongodb installation - CHANGE user and password fields!
MONGODB_HOST=coollabs-mongodb
MONGODB_PORT=27017
MONGODB_USER=supercooldbuser
MONGODB_PASSWORD=developmentPassword4db
MONGODB_DB=coolLabs-prod
# Frontend only variables
VITE_GITHUB_APP_CLIENTID=
VITE_GITHUB_APP_NAME=
# Github OAuth & App secrets and private key - you can get it from Github.
GITHUB_APP_CLIENT_SECRET=
GITHUP_APP_WEBHOOK_SECRET=
# It should look like this. Newlines breaks with \n
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA7Y+Uwkd8FINSwFktWGdtwCaOAazTDYR8ucEzGyR9r+ooJZhF\nOc32qgDSps6Q5DsqPOzvfhiviqU+et9VF+bJhfdzwJ+Le86QZH1RgsDMoY049XvI\nKSwP........"
COOLIFY_APP_ID=
COOLIFY_SECRET_KEY=12341234123412341234123412341234
COOLIFY_DATABASE_URL=file:../db/dev.db
COOLIFY_SENTRY_DSN=
COOLIFY_IS_ON="docker"
COOLIFY_WHITE_LABELED="false"

20
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,20 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript')
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
};

2
.github/FUNDING.yml vendored
View File

@@ -1 +1 @@
ko_fi: andrasbacsai
open_collective: coollabsio

24
.gitignore vendored
View File

@@ -1,12 +1,16 @@
.vscode
.idea
.DS_Store
node_modules
dist
dist-ssr
.routify
/build
/.svelte-kit
/package
/yarn.lock
/.pnpm-store
/ssl
.env
yarn-error.log
api/development/console.log
.pnpm-debug.log
yarn.lock
.pnpm-store
.env.prod
.env.stag
/db/*.db
/db/*.db-journal
/data/haproxy/haproxy.cfg
/data/haproxy/haproxy.cfg.lkg

1
.husky/_/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
pnpm lint-staged

5
.lintstagedrc.json Normal file
View File

@@ -0,0 +1,5 @@
{
"**/*.{js,jsx,ts,tsx,cjs,svelte,json,css,scss,md,yaml}": [
"prettier --ignore-path .gitignore --write --plugin-search-dir=."
]
}

View File

@@ -1,14 +1,6 @@
{
"arrowParens": "avoid",
"bracketSpacing": true,
"printWidth": 80,
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"svelteSortOrder" : "styles-scripts-markup",
"svelteStrictMode": true,
"svelteBracketNewLine": true,
"svelteAllowShorthand": true,
"plugins": ["prettier-plugin-svelte"]
}
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100
}

44
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,44 @@
# Welcome
First of all, thank you for considering to contribute to my project! It means a lot 💜.
# Technical skills required
- Node.js / Javascript
- Svelte / SvelteKit
- Prisma.io
# Recommended Pull Request Guideline
- Fork the project
- Clone your fork repo to local
- Create a new branch
- Push to your fork repo
- Create a pull request: https://github.com/coollabsio/compare
- Write a proper description
- Open the pull request to review
# How to start after you set up your local fork?
This repository best with [pnpm](https://pnpm.io) due to the lock file. I recommend you should try and use `pnpm` as well, because it is cool and efficient!
You need to have [Docker Engine](https://docs.docker.com/engine/install/) installed locally.
## Setup development environment
- Copy `.env.template` to `.env` and set the `COOLIFY_APP_ID` environment variable to something cool.
- Install dependencies with `pnpm install`.
- Need to create a local SQlite database with `pnpm db:push`.
- This will apply all migrations at `db/dev.db`.
- Seed the database with base entities with `pnpm db:seed`
- You can start coding after starting `pnpm dev`.
## Database migrations
During development, if you change the database layout, you need to run `pnpm db:push` to migrate the database and create types for Prisma. You also need to restart the development process.
If the schema is finalized, you need to create a migration file with `pnpm db:migrate <nameOfMigration>` where `nameOfMigration` is given by you. Make it sense. :)
## Tricky parts
- BullMQ, the queue system Coolify is using, cannot be hot reloaded. So if you change anything in the files related to it, you need to restart the development process. I'm actively looking of a different queue/scheduler library. I'm open for discussion!

42
Dockerfile Normal file
View File

@@ -0,0 +1,42 @@
FROM node:16.14.2-alpine as install
WORKDIR /app
RUN apk add --no-cache curl
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@6
RUN pnpm add -g pnpm
COPY package*.json .
RUN pnpm install
FROM node:16.14.2-alpine
ARG TARGETPLATFORM
WORKDIR /app
ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \
PRISMA_MIGRATION_ENGINE_BINARY=/app/prisma-engines/migration-engine \
PRISMA_INTROSPECTION_ENGINE_BINARY=/app/prisma-engines/introspection-engine \
PRISMA_FMT_BINARY=/app/prisma-engines/prisma-fmt \
PRISMA_CLI_QUERY_ENGINE_TYPE=binary \
PRISMA_CLIENT_ENGINE_TYPE=binary
COPY --from=coollabsio/prisma-engine:latest /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/
COPY --from=install /app/node_modules ./node_modules
COPY . .
RUN apk add --no-cache git git-lfs openssh-client curl jq cmake sqlite openssl
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm@6
RUN pnpm add -g pnpm
RUN mkdir -p ~/.docker/cli-plugins/
RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-20.10.9 -o /usr/bin/docker
RUN curl -SL https://cdn.coollabs.io/bin/$TARGETPLATFORM/docker-compose-linux-2.3.4 -o ~/.docker/cli-plugins/docker-compose
RUN chmod +x ~/.docker/cli-plugins/docker-compose /usr/bin/docker
RUN pnpm prisma generate
RUN pnpm build
EXPOSE 3000
CMD ["pnpm", "start"]

129
README.md
View File

@@ -1,93 +1,98 @@
# About
# Coolify
https://andrasbacsai.com/farewell-netlify-and-heroku-after-3-days-of-coding
An open-source & self-hostable Heroku / Netlify alternative.
# Features
- Deploy your Node.js, static sites, PHP or any custom application (with custom Dockerfile) just by pushing code to git.
- Hassle-free installation and upgrade process.
- One-click MongoDB, MySQL, PostgreSQL, CouchDB deployments!
## Live Demo
# Upcoming features
- Backups & monitoring.
- User analytics with privacy in mind.
- And much more (see [Roadmap](https://github.com/coollabsio/coolify/projects/1)).
https://demo.coolify.io/
(If it is unresponsive, that means someone overloaded the server. 🙃)
# FAQ
Q: What is a buildpack?
## How to install
A: It defines your application's final form.
`Static` means that it will be hosted as a static site.
`NodeJs` means that it will be started as a node application.
Installation is automated with the following command:
# Screenshots
```bash
/bin/bash -c "$(curl -fsSL https://get.coollabs.io/coolify/install.sh)"
```
[Login](https://coollabs.io/coolify/login.jpg)
If you would like no questions during installation
[Applications](https://coollabs.io/coolify/applications.jpg)
## Features
[Databases](https://coollabs.io/coolify/databases.jpg)
### Git Sources
[Configuration](https://coollabs.io/coolify/configuration.jpg)
You can use the following Git Sources to be auto-deployed to your Coolifyt instance! (Self hosted versions also supported.)
[Settings](https://coollabs.io/coolify/settings.jpg)
- Github
- GitLab
- Bitbucket (WIP)
[Logs](https://coollabs.io/coolify/logs.jpg)
### Destinations
# Getting Started
You can deploy your applications to the following destinations:
Automatically: `/bin/bash -c "$(curl -fsSL https://get.coollabs.io/coolify/install.sh)"`
- Local Docker Engine
- Remote Docker Engine (WIP)
- Kubernetes (WIP)
Manually:
### Requirements before installation
- [Docker](https://docs.docker.com/engine/install/) version 20+
- Docker in [swarm mode enabled](https://docs.docker.com/engine/reference/commandline/swarm_init/) (should be set manually before installation)
- A [MongoDB](https://docs.mongodb.com/manual/installation/) instance.
- We have a [simple installation](https://github.com/coollabsio/infrastructure/tree/main/mongo) if you need one
- A configured DNS entry (see `.env.template`)
- [Github App](https://docs.github.com/en/developers/apps/creating-a-github-app)
### Applications
- GitHub App name: could be anything weird
- Homepage URL: https://yourdomain
These are the predefined build packs, but with the Docker build pack, you can host basically anything that is hostable with a single Dockerfile.
Identifying and authorizing users:
- Callback URL: https://yourdomain/api/v1/login/github/app
- Request user authorization (OAuth) during installation -> Check!
- Static sites
- NodeJS
- VueJS
- NuxtJS
- NextJS
- React/Preact
- NextJS
- Gatsby
- Svelte
- PHP
- Rust
- Docker
Webhook:
- Active -> Check!
- Webhook URL: https://yourdomain/api/v1/webhooks/deploy
- Webhook Secret: it should be super secret
### Databases
Repository permissions:
- Contents: Read-only
- Metadata: Read-only
User permissions:
- Email: Read-only
One-click database is ready to be used internally or shared over the internet:
Subscribe to events:
- Push -> Check!
- MongoDB
- MySQL
- PostgreSQL
- CouchDB
- Redis
### Installation
- Clone this repository: `git clone git@github.com:coollabsio/coolify.git`
- Set `.env` (see `.env.template`)
- Installation: `bash install.sh all`
### One-click services
## Manual updating process (You probably never need to do this!)
### Update everything (proxy+coolify)
- `bash install.sh all`
You can host cool open-source services as well:
### Update coolify only
- `bash install.sh coolify`
- [WordPress](https://wordpress.org)
- [Ghost](https://ghost.org)
- [Plausible Analytics](https://plausible.io)
- [NocoDB](https://nocodb.com)
- [VSCode Server](https://github.com/cdr/code-server)
- [MinIO](https://min.io)
- [VaultWarden](https://github.com/dani-garcia/vaultwarden)
- [LanguageTool](https://languagetool.org)
- [n8n](https://n8n.io)
- [Uptime Kuma](https://github.com/louislam/uptime-kuma)
### Update proxy only
- `bash install.sh proxy`
## Migration from v1
A fresh installation is necessary. v2 is not compatible with v1.
## Support
# Contact
- Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai)
- Telegram: [@andrasbacsai](https://t.me/andrasbacsai)
- Email: [andras@coollabs.io](mailto:andras@coollabs.io)
- Discord: [Invitation](https://discord.gg/xhBCC7eGKw)
## Contribute
See [our contribution guide](./CONTRIBUTING.md).
## License
# License
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Please see the [LICENSE](/LICENSE) file in our repository for the full text.

View File

@@ -1,28 +0,0 @@
module.exports = async function (fastify, opts) {
// Private routes
fastify.register(async function (server) {
if (process.env.NODE_ENV === 'production') server.register(require('./plugins/authentication'))
server.register(require('./routes/v1/upgrade'), { prefix: '/upgrade' })
server.register(require('./routes/v1/settings'), { prefix: '/settings' })
server.register(require('./routes/v1/dashboard'), { prefix: '/dashboard' })
server.register(require('./routes/v1/config'), { prefix: '/config' })
server.register(require('./routes/v1/application/remove'), { prefix: '/application/remove' })
server.register(require('./routes/v1/application/logs'), { prefix: '/application/logs' })
server.register(require('./routes/v1/application/check'), { prefix: '/application/check' })
server.register(require('./routes/v1/application/deploy'), { prefix: '/application/deploy' })
server.register(require('./routes/v1/application/deploy/logs'), { prefix: '/application/deploy/logs' })
server.register(require('./routes/v1/databases'), { prefix: '/databases' })
server.register(require('./routes/v1/server'), { prefix: '/server' })
})
// Public routes
fastify.register(require('./routes/v1/verify'), { prefix: '/verify' })
fastify.register(require('./routes/v1/login/github'), {
prefix: '/login/github'
})
fastify.register(require('./routes/v1/webhooks/deploy'), {
prefix: '/webhooks/deploy'
})
fastify.register(require('./routes/v1/undead'), {
prefix: '/undead'
})
}

View File

@@ -1,19 +0,0 @@
const fs = require('fs').promises
const { streamEvents, docker } = require('../../libs/docker')
module.exports = async function (configuration) {
try {
const path = `${configuration.general.workdir}/${configuration.build.directory ? configuration.build.directory : ''}`
if (fs.stat(`${path}/Dockerfile`)) {
const stream = await docker.engine.buildImage(
{ src: ['.'], context: path },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} else {
throw { error: 'No custom dockerfile found.', type: 'app' }
}
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,27 +0,0 @@
const fs = require('fs').promises
const { streamEvents, docker } = require('../libs/docker')
const buildImageNodeDocker = (configuration) => {
return [
'FROM node:lts',
'WORKDIR /usr/src/app',
`COPY ${configuration.build.directory} ./`,
configuration.build.command.installation && `RUN ${configuration.build.command.installation}`,
`RUN ${configuration.build.command.build}`
].join('\n')
}
async function buildImage (configuration) {
try {
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, buildImageNodeDocker(configuration))
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} catch (error) {
throw { error, type: 'server' }
}
}
module.exports = {
buildImage
}

View File

@@ -1,7 +0,0 @@
const static = require('./static')
const nodejs = require('./nodejs')
const php = require('./php')
const custom = require('./custom')
const rust = require('./rust')
module.exports = { static, nodejs, php, custom, rust }

View File

@@ -1,30 +0,0 @@
const fs = require('fs').promises
const { buildImage } = require('../helpers')
const { streamEvents, docker } = require('../../libs/docker')
// `HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost:${configuration.publish.port}${configuration.publish.path} || exit 1`,
const publishNodejsDocker = (configuration) => {
return [
'FROM node:lts',
'WORKDIR /usr/src/app',
configuration.build.command.build
? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./`
: `COPY ${configuration.build.directory} ./`,
configuration.build.command.installation && `RUN ${configuration.build.command.installation}`,
`EXPOSE ${configuration.publish.port}`,
'CMD [ "yarn", "start" ]'
].join('\n')
}
module.exports = async function (configuration) {
try {
if (configuration.build.command.build) await buildImage(configuration)
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishNodejsDocker(configuration))
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,26 +0,0 @@
const fs = require('fs').promises
const { streamEvents, docker } = require('../../libs/docker')
// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1',
const publishPHPDocker = (configuration) => {
return [
'FROM php:apache',
'RUN a2enmod rewrite',
'WORKDIR /usr/src/app',
`COPY .${configuration.build.directory} /var/www/html`,
'EXPOSE 80',
' CMD ["apache2-foreground"]'
].join('\n')
}
module.exports = async function (configuration) {
try {
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishPHPDocker(configuration))
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,64 +0,0 @@
const fs = require('fs').promises
const { streamEvents, docker } = require('../../libs/docker')
const { execShellAsync } = require('../../libs/common')
const TOML = require('@iarna/toml')
const publishRustDocker = (configuration, custom) => {
return [
'FROM rust:latest',
'WORKDIR /app',
`COPY --from=${configuration.build.container.name}:cache /app/target target`,
`COPY --from=${configuration.build.container.name}:cache /usr/local/cargo /usr/local/cargo`,
'COPY . .',
`RUN cargo build --release --bin ${custom.name}`,
'FROM debian:buster-slim',
'WORKDIR /app',
'RUN apt-get update -y && apt-get install -y --no-install-recommends openssl libcurl4 ca-certificates && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*',
'RUN update-ca-certificates',
`COPY --from=${configuration.build.container.name}:cache /app/target/release/${custom.name} ${custom.name}`,
`EXPOSE ${configuration.publish.port}`,
`CMD ["/app/${custom.name}"]`
].join('\n')
}
const cacheRustDocker = (configuration, custom) => {
return [
`FROM rust:latest AS planner-${configuration.build.container.name}`,
'WORKDIR /app',
'RUN cargo install cargo-chef',
'COPY . .',
'RUN cargo chef prepare --recipe-path recipe.json',
'FROM rust:latest',
'WORKDIR /app',
'RUN cargo install cargo-chef',
`COPY --from=planner-${configuration.build.container.name} /app/recipe.json recipe.json`,
'RUN cargo chef cook --release --recipe-path recipe.json'
].join('\n')
}
module.exports = async function (configuration) {
try {
const cargoToml = await execShellAsync(`cat ${configuration.general.workdir}/Cargo.toml`)
const parsedToml = TOML.parse(cargoToml)
const custom = {
name: parsedToml.package.name
}
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, cacheRustDocker(configuration, custom))
let stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:cache` }
)
await streamEvents(stream, configuration)
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishRustDocker(configuration, custom))
stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,32 +0,0 @@
const fs = require('fs').promises
const { buildImage } = require('../helpers')
const { streamEvents, docker } = require('../../libs/docker')
// 'HEALTHCHECK --timeout=10s --start-period=10s --interval=5s CMD curl -I -s -f http://localhost/ || exit 1',
const publishStaticDocker = (configuration) => {
return [
'FROM nginx:stable-alpine',
'COPY nginx.conf /etc/nginx/nginx.conf',
'WORKDIR /usr/share/nginx/html',
configuration.build.command.build
? `COPY --from=${configuration.build.container.name}:${configuration.build.container.tag} /usr/src/app/${configuration.publish.directory} ./`
: `COPY ${configuration.build.directory} ./`,
'EXPOSE 80',
'CMD ["nginx", "-g", "daemon off;"]'
].join('\n')
}
module.exports = async function (configuration) {
try {
if (configuration.build.command.build) await buildImage(configuration)
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishStaticDocker(configuration))
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }
)
await streamEvents(stream, configuration)
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,36 +0,0 @@
const mongoose = require('mongoose')
const { MongoMemoryServer } = require('mongodb-memory-server-core')
const mongoServer = new MongoMemoryServer({
instance: {
port: 27017,
dbName: 'coolify',
storageEngine: 'wiredTiger'
},
binary: {
version: '4.4.3'
}
})
mongoose.Promise = Promise
mongoServer.getUri().then((mongoUri) => {
const mongooseOpts = {
useNewUrlParser: true,
useUnifiedTopology: true
}
mongoose.connect(mongoUri, mongooseOpts)
mongoose.connection.on('error', (e) => {
if (e.message.code === 'ETIMEDOUT') {
console.log(e)
mongoose.connect(mongoUri, mongooseOpts)
}
console.log(e)
})
mongoose.connection.once('open', () => {
console.log(`Started in-memory mongodb ${mongoUri}`)
})
})

View File

@@ -1,39 +0,0 @@
const packs = require('../../../buildPacks')
const { saveAppLog } = require('../../logging')
const Deployment = require('../../../models/Deployment')
module.exports = async function (configuration) {
const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish
const deployId = configuration.general.deployId
const execute = packs[configuration.build.pack]
if (execute) {
try {
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'inprogress' })
await saveAppLog('### Building application.', configuration)
await execute(configuration)
await saveAppLog('### Building done.', configuration)
} catch (error) {
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
if (error.stack) throw { error: error.stack, type: 'server' }
throw { error, type: 'app' }
}
} else {
try {
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'failed' })
} catch (error) {
// Hmm.
}
throw { error: 'No buildpack found.', type: 'app' }
}
}

View File

@@ -1,41 +0,0 @@
const { docker } = require('../../docker')
const { execShellAsync } = require('../../common')
const Deployment = require('../../../models/Deployment')
async function purgeImagesContainers () {
try {
await execShellAsync('docker container prune -f')
await execShellAsync('docker image prune -f --filter=label!=coolify-reserve=true')
} catch (error) {
throw { error, type: 'server' }
}
}
async function cleanupStuckedDeploymentsInDB (configuration) {
const { id } = configuration.repository
const deployId = configuration.general.deployId
try {
// Cleanup stucked deployments.
const deployments = await Deployment.find({ repoId: id, deployId: { $ne: deployId }, progress: { $in: ['queued', 'inprogress'] } })
for (const deployment of deployments) {
await Deployment.findByIdAndUpdate(deployment._id, { $set: { progress: 'failed' } })
}
} catch (error) {
throw { error, type: 'server' }
}
}
async function deleteSameDeployments (configuration) {
try {
await (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application').map(async s => {
const running = JSON.parse(s.Spec.Labels.configuration)
if (running.repository.id === configuration.repository.id && running.repository.branch === configuration.repository.branch) {
await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`)
}
})
} catch (error) {
throw { error, type: 'server' }
}
}
module.exports = { cleanupStuckedDeploymentsInDB, deleteSameDeployments, purgeImagesContainers }

View File

@@ -1,145 +0,0 @@
const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator')
const cuid = require('cuid')
const crypto = require('crypto')
const { docker } = require('../docker')
const { execShellAsync } = require('../common')
function getUniq () {
return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 })
}
function setDefaultConfiguration (configuration) {
try {
const nickname = getUniq()
const deployId = cuid()
const shaBase = JSON.stringify({ repository: configuration.repository })
const sha256 = crypto.createHash('sha256').update(shaBase).digest('hex')
const baseServiceConfiguration = {
replicas: 1,
restart_policy: {
condition: 'any',
max_attempts: 3
},
update_config: {
parallelism: 1,
delay: '10s',
order: 'start-first'
},
rollback_config: {
parallelism: 1,
delay: '10s',
order: 'start-first',
failure_action: 'rollback'
}
}
configuration.build.container.name = sha256.slice(0, 15)
configuration.general.nickname = nickname
configuration.general.deployId = deployId
configuration.general.workdir = `/tmp/${deployId}`
if (!configuration.publish.path) configuration.publish.path = '/'
if (!configuration.publish.port) {
if (configuration.build.pack === 'php') {
configuration.publish.port = 80
} else if (configuration.build.pack === 'static') {
configuration.publish.port = 80
} else if (configuration.build.pack === 'nodejs') {
configuration.publish.port = 3000
} else if (configuration.build.pack === 'rust') {
configuration.publish.port = 3000
}
}
if (!configuration.build.directory) {
configuration.build.directory = '/'
}
if (!configuration.publish.directory) {
configuration.publish.directory = '/'
}
if (configuration.build.pack === 'static' || configuration.build.pack === 'nodejs') {
if (!configuration.build.command.installation) configuration.build.command.installation = 'yarn install'
}
configuration.build.container.baseSHA = crypto.createHash('sha256').update(JSON.stringify(baseServiceConfiguration)).digest('hex')
configuration.baseServiceConfiguration = baseServiceConfiguration
return configuration
} catch (error) {
throw { error, type: 'server' }
}
}
async function updateServiceLabels (configuration) {
// In case of any failure during deployment, still update the current configuration.
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
const found = services.find(s => {
const config = JSON.parse(s.Spec.Labels.configuration)
if (config.repository.id === configuration.repository.id && config.repository.branch === configuration.repository.branch) {
return config
}
return null
})
if (found) {
const { ID } = found
try {
const Labels = { ...JSON.parse(found.Spec.Labels.configuration), ...configuration }
await execShellAsync(`docker service update --label-add configuration='${JSON.stringify(Labels)}' --label-add com.docker.stack.image='${configuration.build.container.name}:${configuration.build.container.tag}' ${ID}`)
} catch (error) {
console.log(error)
}
}
}
async function precheckDeployment ({ services, configuration }) {
let foundService = false
let configChanged = false
let imageChanged = false
let forceUpdate = false
for (const service of services) {
const running = JSON.parse(service.Spec.Labels.configuration)
if (running) {
if (running.repository.id === configuration.repository.id && running.repository.branch === configuration.repository.branch) {
// Base service configuration changed
if (!running.build.container.baseSHA || running.build.container.baseSHA !== configuration.build.container.baseSHA) {
forceUpdate = true
}
// If the deployment is in error state, forceUpdate
const state = await execShellAsync(`docker stack ps ${running.build.container.name} --format '{{ json . }}'`)
const isError = state.split('\n').filter(n => n).map(s => JSON.parse(s)).filter(n => n.DesiredState !== 'Running' && n.Image.split(':')[1] === running.build.container.tag)
if (isError.length > 0) forceUpdate = true
foundService = true
const runningWithoutContainer = JSON.parse(JSON.stringify(running))
delete runningWithoutContainer.build.container
const configurationWithoutContainer = JSON.parse(JSON.stringify(configuration))
delete configurationWithoutContainer.build.container
// If only the configuration changed
if (JSON.stringify(runningWithoutContainer.build) !== JSON.stringify(configurationWithoutContainer.build) || JSON.stringify(runningWithoutContainer.publish) !== JSON.stringify(configurationWithoutContainer.publish)) configChanged = true
// If only the image changed
if (running.build.container.tag !== configuration.build.container.tag) imageChanged = true
// If build pack changed, forceUpdate the service
if (running.build.pack !== configuration.build.pack) forceUpdate = true
}
}
}
if (forceUpdate) {
imageChanged = false
configChanged = false
}
return {
foundService,
imageChanged,
configChanged,
forceUpdate
}
}
module.exports = { setDefaultConfiguration, updateServiceLabels, precheckDeployment }

View File

@@ -1,64 +0,0 @@
const fs = require('fs').promises
module.exports = async function (configuration) {
try {
// TODO: Write full .dockerignore for all deployments!!
if (configuration.build.pack === 'php') {
await fs.writeFile(`${configuration.general.workdir}/.htaccess`, `
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php [QSA,L]
`)
}
// await fs.writeFile(`${configuration.general.workdir}/.dockerignore`, 'node_modules')
if (configuration.build.pack === 'static') {
await fs.writeFile(
`${configuration.general.workdir}/nginx.conf`,
`user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
access_log off;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/index.html $uri/ /index.html =404;
}
error_page 404 /50x.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
`
)
}
} catch (error) {
throw { error, type: 'server' }
}
}

View File

@@ -1,82 +0,0 @@
const yaml = require('js-yaml')
const fs = require('fs').promises
const { execShellAsync } = require('../../common')
const { docker } = require('../../docker')
const { saveAppLog } = require('../../logging')
const { deleteSameDeployments } = require('../cleanup')
module.exports = async function (configuration, imageChanged) {
try {
const generateEnvs = {}
for (const secret of configuration.publish.secrets) {
generateEnvs[secret.name] = secret.value
}
const containerName = configuration.build.container.name
// Only save SHA256 of it in the configuration label
const baseServiceConfiguration = configuration.baseServiceConfiguration
delete configuration.baseServiceConfiguration
const stack = {
version: '3.8',
services: {
[containerName]: {
image: `${configuration.build.container.name}:${configuration.build.container.tag}`,
networks: [`${docker.network}`],
environment: generateEnvs,
deploy: {
...baseServiceConfiguration,
labels: [
'managedBy=coolify',
'type=application',
'configuration=' + JSON.stringify(configuration),
'traefik.enable=true',
'traefik.http.services.' +
configuration.build.container.name +
`.loadbalancer.server.port=${configuration.publish.port}`,
'traefik.http.routers.' +
configuration.build.container.name +
'.entrypoints=websecure',
'traefik.http.routers.' +
configuration.build.container.name +
'.rule=Host(`' +
configuration.publish.domain +
'`) && PathPrefix(`' +
configuration.publish.path +
'`)',
'traefik.http.routers.' +
configuration.build.container.name +
'.tls.certresolver=letsencrypt',
'traefik.http.routers.' +
configuration.build.container.name +
'.middlewares=global-compress'
]
}
}
},
networks: {
[`${docker.network}`]: {
external: true
}
}
}
await saveAppLog('### Publishing.', configuration)
await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack))
if (imageChanged) {
// console.log('image changed')
await execShellAsync(`docker service update --image ${configuration.build.container.name}:${configuration.build.container.tag} ${configuration.build.container.name}_${configuration.build.container.name}`)
} else {
// console.log('new deployment or force deployment or config changed')
await deleteSameDeployments(configuration)
await execShellAsync(
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy --prune -c - ${containerName}`
)
}
await saveAppLog('### Published done!', configuration)
} catch (error) {
console.log(error)
await saveAppLog(`Error occured during deployment: ${error.message}`, configuration)
throw { error, type: 'server' }
}
}

View File

@@ -1,44 +0,0 @@
const jwt = require('jsonwebtoken')
const axios = require('axios')
const { execShellAsync, cleanupTmp } = require('../../common')
module.exports = async function (configuration) {
const { workdir } = configuration.general
const { organization, name, branch } = configuration.repository
const github = configuration.github
const githubPrivateKey = process.env.GITHUB_APP_PRIVATE_KEY.replace(/\\n/g, '\n').replace(/"/g, '')
const payload = {
iat: Math.round(new Date().getTime() / 1000),
exp: Math.round(new Date().getTime() / 1000 + 60),
iss: parseInt(github.app.id)
}
try {
const jwtToken = jwt.sign(payload, githubPrivateKey, {
algorithm: 'RS256'
})
const accessToken = await axios({
method: 'POST',
url: `https://api.github.com/app/installations/${github.installation.id}/access_tokens`,
data: {},
headers: {
Authorization: 'Bearer ' + jwtToken,
Accept: 'application/vnd.github.machine-man-preview+json'
}
})
await execShellAsync(
`mkdir -p ${workdir} && git clone -q -b ${branch} https://x-access-token:${accessToken.data.token}@github.com/${organization}/${name}.git ${workdir}/`
)
configuration.build.container.tag = (
await execShellAsync(`cd ${configuration.general.workdir}/ && git rev-parse HEAD`)
)
.replace('\n', '')
.slice(0, 7)
} catch (error) {
cleanupTmp(workdir)
if (error.stack) console.log(error.stack)
throw { error, type: 'server' }
}
}

View File

@@ -1,44 +0,0 @@
const dayjs = require('dayjs')
const { saveServerLog } = require('../logging')
const { cleanupTmp } = require('../common')
const { saveAppLog } = require('../logging')
const copyFiles = require('./deploy/copyFiles')
const buildContainer = require('./build/container')
const deploy = require('./deploy/deploy')
const Deployment = require('../../models/Deployment')
const { cleanupStuckedDeploymentsInDB, purgeImagesContainers } = require('./cleanup')
const { updateServiceLabels } = require('./configuration')
async function queueAndBuild (configuration, imageChanged) {
const { id, organization, name, branch } = configuration.repository
const { domain } = configuration.publish
const { deployId, nickname, workdir } = configuration.general
try {
await new Deployment({
repoId: id, branch, deployId, domain, organization, name, nickname
}).save()
await saveAppLog(`${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} Queued.`, configuration)
await copyFiles(configuration)
await buildContainer(configuration)
await deploy(configuration, imageChanged)
await Deployment.findOneAndUpdate(
{ repoId: id, branch, deployId, organization, name, domain },
{ repoId: id, branch, deployId, organization, name, domain, progress: 'done' })
await updateServiceLabels(configuration)
cleanupTmp(workdir)
await purgeImagesContainers()
} catch (error) {
await cleanupStuckedDeploymentsInDB(configuration)
cleanupTmp(workdir)
const { type } = error.error
if (type === 'app') {
await saveAppLog(error.error, configuration, true)
} else {
await saveServerLog({ event: error.error, configuration })
}
}
}
module.exports = { queueAndBuild }

View File

@@ -1,98 +0,0 @@
const crypto = require('crypto')
const shell = require('shelljs')
const jsonwebtoken = require('jsonwebtoken')
const { docker } = require('./docker')
const User = require('../models/User')
const algorithm = 'aes-256-cbc'
const key = process.env.SECRETS_ENCRYPTION_KEY
function delay (t) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve('OK')
}, t)
})
}
async function verifyUserId (authorization) {
try {
const token = authorization.split(' ')[1]
const verify = jsonwebtoken.verify(token, process.env.JWT_SIGN_KEY)
const found = await User.findOne({ uid: verify.jti })
if (found) {
return true
} else {
return false
}
} catch (error) {
return false
}
}
function execShellAsync (cmd, opts = {}) {
try {
return new Promise(function (resolve, reject) {
shell.config.silent = true
shell.exec(cmd, opts, function (code, stdout, stderr) {
if (code !== 0) return reject(new Error(stderr))
return resolve(stdout)
})
})
} catch (error) {
return new Error('Oops')
}
}
function cleanupTmp (dir) {
if (dir !== '/') shell.rm('-fr', dir)
}
async function checkImageAvailable (name) {
let cacheAvailable = false
try {
await docker.engine.getImage(name).get()
cacheAvailable = true
} catch (e) {
// Cache image not found
}
return cacheAvailable
}
function encryptData (text) {
const iv = crypto.randomBytes(16)
const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv)
let encrypted = cipher.update(text)
encrypted = Buffer.concat([encrypted, cipher.final()])
return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') }
}
function decryptData (text) {
const iv = Buffer.from(text.iv, 'hex')
const encryptedText = Buffer.from(text.encryptedData, 'hex')
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv)
let decrypted = decipher.update(encryptedText)
decrypted = Buffer.concat([decrypted, decipher.final()])
return decrypted.toString()
}
function createToken (payload) {
const { uuid } = payload
return jsonwebtoken.sign({}, process.env.JWT_SIGN_KEY, {
expiresIn: 15778800,
algorithm: 'HS256',
audience: 'coolify',
issuer: 'coolify',
jwtid: uuid,
subject: `User:${uuid}`,
notBefore: -1000
})
}
module.exports = {
delay,
createToken,
execShellAsync,
cleanupTmp,
checkImageAvailable,
encryptData,
decryptData,
verifyUserId
}

View File

@@ -1,31 +0,0 @@
const Dockerode = require('dockerode')
const { saveAppLog } = require('./logging')
const docker = {
engine: new Dockerode({
socketPath: process.env.DOCKER_ENGINE
}),
network: process.env.DOCKER_NETWORK
}
async function streamEvents (stream, configuration) {
try {
await new Promise((resolve, reject) => {
docker.engine.modem.followProgress(stream, onFinished, onProgress)
function onFinished (err, res) {
if (err) reject(err)
resolve(res)
}
function onProgress (event) {
if (event.error) {
reject(event.error)
return
}
saveAppLog(event.stream, configuration)
}
})
} catch (error) {
throw { error, type: 'app' }
}
}
module.exports = { streamEvents, docker }

View File

@@ -1,59 +0,0 @@
const ApplicationLog = require('../models/Logs/Application')
const ServerLog = require('../models/Logs/Server')
const dayjs = require('dayjs')
function generateTimestamp () {
return `${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} `
}
async function saveAppLog (event, configuration, isError) {
try {
const deployId = configuration.general.deployId
const repoId = configuration.repository.id
const branch = configuration.repository.branch
if (isError) {
// console.log(event, config, isError)
let clearedEvent = null
if (event.error) clearedEvent = '[ERROR] ' + generateTimestamp() + event.error.replace(/(\r\n|\n|\r)/gm, '')
else if (event) clearedEvent = '[ERROR] ' + generateTimestamp() + event.replace(/(\r\n|\n|\r)/gm, '')
try {
await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save()
} catch (error) {
console.log(error)
}
} else {
if (event && event !== '\n') {
const clearedEvent = '[INFO] ' + generateTimestamp() + event.replace(/(\r\n|\n|\r)/gm, '')
try {
await new ApplicationLog({ repoId, branch, deployId, event: clearedEvent }).save()
} catch (error) {
console.log(error)
}
}
}
} catch (error) {
console.log(error)
return error
}
}
async function saveServerLog ({ event, configuration, type }) {
try {
if (configuration) {
const deployId = configuration.general.deployId
const repoId = configuration.repository.id
const branch = configuration.repository.branch
await new ApplicationLog({ repoId, branch, deployId, event: `[SERVER ERROR 😖]: ${event}` }).save()
}
await new ServerLog({ event, type }).save()
} catch (error) {
// Hmm.
}
}
module.exports = {
saveAppLog,
saveServerLog
}

View File

@@ -1,16 +0,0 @@
const mongoose = require('mongoose')
const deploymentSchema = mongoose.Schema(
{
deployId: { type: String, required: true },
nickname: { type: String, required: true },
repoId: { type: Number, required: true },
organization: { type: String, required: true },
name: { type: String, required: true },
branch: { type: String, required: true },
domain: { type: String, required: true },
progress: { type: String, require: true, default: 'queued' }
},
{ timestamps: true }
)
module.exports = mongoose.model('deployment', deploymentSchema)

View File

@@ -1,10 +0,0 @@
const mongoose = require('mongoose')
const logSchema = mongoose.Schema(
{
deployId: { type: String, required: true },
event: { type: String, required: true }
},
{ timestamps: { createdAt: 'createdAt', updatedAt: false } }
)
module.exports = mongoose.model('logs-application', logSchema)

View File

@@ -1,13 +0,0 @@
const mongoose = require('mongoose')
const { version } = require('../../../package.json')
const logSchema = mongoose.Schema(
{
version: { type: String, required: true, default: version },
type: { type: String, required: true, enum: ['API', 'UPGRADE-P-1', 'UPGRADE-P-2'], default: 'API' },
event: { type: String, required: true },
seen: { type: Boolean, required: true, default: false }
},
{ timestamps: { createdAt: 'createdAt', updatedAt: false } }
)
module.exports = mongoose.model('logs-server', logSchema)

View File

@@ -1,11 +0,0 @@
const mongoose = require('mongoose')
const settingsSchema = mongoose.Schema(
{
applicationName: { type: String, required: true, default: 'coolify' },
allowRegistration: { type: Boolean, required: true, default: false }
},
{ timestamps: true }
)
module.exports = mongoose.model('settings', settingsSchema)

View File

@@ -1,12 +0,0 @@
const mongoose = require('mongoose')
const userSchema = mongoose.Schema(
{
email: { type: String, required: true },
avatar: { type: String },
uid: { type: String, required: true }
},
{ timestamps: true }
)
module.exports = mongoose.model('user', userSchema)

View File

@@ -1,21 +0,0 @@
const fp = require('fastify-plugin')
const User = require('../models/User')
module.exports = fp(async function (fastify, options, next) {
fastify.register(require('fastify-jwt'), {
secret: fastify.config.JWT_SIGN_KEY
})
fastify.addHook('onRequest', async (request, reply) => {
try {
const { jti } = await request.jwtVerify()
const found = await User.findOne({ uid: jti })
if (found) {
return true
} else {
reply.code(401).send('Unauthorized')
}
} catch (err) {
reply.code(401).send('Unauthorized')
}
})
next()
})

View File

@@ -1,40 +0,0 @@
const { verifyUserId } = require('../../../libs/common')
const { setDefaultConfiguration } = require('../../../libs/applications/configuration')
const { docker } = require('../../../libs/docker')
module.exports = async function (fastify) {
fastify.post('/', async (request, reply) => {
try {
if (!await verifyUserId(request.headers.authorization)) {
reply.code(500).send({ error: 'Invalid request' })
return
}
const configuration = setDefaultConfiguration(request.body)
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
let foundDomain = false
for (const service of services) {
const running = JSON.parse(service.Spec.Labels.configuration)
if (running) {
if (
running.publish.domain === configuration.publish.domain &&
running.repository.id !== configuration.repository.id &&
running.publish.path === configuration.publish.path
) {
foundDomain = true
}
}
}
if (fastify.config.DOMAIN === configuration.publish.domain) foundDomain = true
if (foundDomain) {
reply.code(500).send({ message: 'Domain already in use.' })
return
}
return { message: 'OK' }
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,74 +0,0 @@
const { verifyUserId, cleanupTmp } = require('../../../../libs/common')
const Deployment = require('../../../../models/Deployment')
const { queueAndBuild } = require('../../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../../libs/applications/configuration')
const { docker } = require('../../../../libs/docker')
const cloneRepository = require('../../../../libs/applications/github/cloneRepository')
module.exports = async function (fastify) {
// const postSchema = {
// body: {
// type: "object",
// properties: {
// ref: { type: "string" },
// repository: {
// type: "object",
// properties: {
// id: { type: "number" },
// full_name: { type: "string" },
// },
// required: ["id", "full_name"],
// },
// installation: {
// type: "object",
// properties: {
// id: { type: "number" },
// },
// required: ["id"],
// },
// },
// required: ["ref", "repository", "installation"],
// },
// };
fastify.post('/', async (request, reply) => {
try {
await verifyUserId(request.headers.authorization)
} catch (error) {
reply.code(500).send({ error: 'Invalid request' })
return
}
try {
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
const configuration = setDefaultConfiguration(request.body)
await cloneRepository(configuration)
const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ services, configuration })
if (foundService && !forceUpdate && !imageChanged && !configChanged) {
cleanupTmp(configuration.general.workdir)
reply.code(500).send({ message: 'Nothing changed, no need to redeploy.' })
return
}
const alreadyQueued = await Deployment.find({
repoId: configuration.repository.id,
branch: configuration.repository.branch,
organization: configuration.repository.organization,
name: configuration.repository.name,
domain: configuration.publish.domain,
progress: { $in: ['queued', 'inprogress'] }
})
if (alreadyQueued.length > 0) {
reply.code(200).send({ message: 'Already in the queue.' })
return
}
queueAndBuild(configuration, imageChanged)
reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name })
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,66 +0,0 @@
const ApplicationLog = require('../../../../models/Logs/Application')
const Deployment = require('../../../../models/Deployment')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
const relativeTime = require('dayjs/plugin/relativeTime')
dayjs.extend(utc)
dayjs.extend(relativeTime)
module.exports = async function (fastify) {
const getLogSchema = {
querystring: {
type: 'object',
properties: {
repoId: { type: 'string' },
branch: { type: 'string' }
},
required: ['repoId', 'branch']
}
}
fastify.get('/', { schema: getLogSchema }, async (request, reply) => {
try {
const { repoId, branch, page } = request.query
const onePage = 5
const show = Number(page) * onePage || 5
const deploy = await Deployment.find({ repoId, branch })
.select('-_id -__v -repoId')
.sort({ createdAt: 'desc' })
.limit(show)
const finalLogs = deploy.map(d => {
const finalLogs = { ...d._doc }
const updatedAt = dayjs(d.updatedAt).utc()
finalLogs.took = updatedAt.diff(dayjs(d.createdAt)) / 1000
finalLogs.since = updatedAt.fromNow()
return finalLogs
})
return finalLogs
} catch (error) {
throw { error, type: 'server' }
}
})
fastify.get('/:deployId', async (request, reply) => {
const { deployId } = request.params
try {
const logs = await ApplicationLog.find({ deployId })
.select('-_id -__v')
.sort({ createdAt: 'asc' })
const deploy = await Deployment.findOne({ deployId })
.select('-_id -__v')
.sort({ createdAt: 'desc' })
const finalLogs = {}
finalLogs.progress = deploy.progress
finalLogs.events = logs.map(log => log.event)
finalLogs.human = dayjs(deploy.updatedAt).from(dayjs(deploy.updatedAt))
return finalLogs
} catch (e) {
throw new Error('No logs found')
}
})
}

View File

@@ -1,14 +0,0 @@
const { docker } = require('../../../libs/docker')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
try {
const { name } = request.query
const service = await docker.engine.getService(`${name}_${name}`)
const logs = (await service.logs({ stdout: true, stderr: true, timestamps: true })).toString().split('\n').map(l => l.slice(8)).filter((a) => a)
return { logs }
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,35 +0,0 @@
const { docker } = require('../../../libs/docker')
const { execShellAsync } = require('../../../libs/common')
const ApplicationLog = require('../../../models/Logs/Application')
const Deployment = require('../../../models/Deployment')
module.exports = async function (fastify) {
fastify.post('/', async (request, reply) => {
const { organization, name, branch } = request.body
let found = false
try {
(await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application').map(s => {
const running = JSON.parse(s.Spec.Labels.configuration)
if (running.repository.organization === organization &&
running.repository.name === name &&
running.repository.branch === branch) {
found = running
}
return null
})
if (found) {
const deploys = await Deployment.find({ organization, branch, name })
for (const deploy of deploys) {
await ApplicationLog.deleteMany({ deployId: deploy.deployId })
await Deployment.deleteMany({ deployId: deploy.deployId })
}
await execShellAsync(`docker stack rm ${found.build.container.name}`)
reply.code(200).send({ organization, name, branch })
} else {
reply.code(500).send({ message: 'Nothing to do.' })
}
} catch (error) {
reply.code(500).send({ message: 'Nothing to do.' })
}
})
}

View File

@@ -1,28 +0,0 @@
const { docker } = require('../../libs/docker')
module.exports = async function (fastify) {
fastify.post('/', async (request, reply) => {
const { name, organization, branch } = request.body
const services = await docker.engine.listServices()
const applications = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
const found = applications.find(r => {
const configuration = r.Spec.Labels.configuration ? JSON.parse(r.Spec.Labels.configuration) : null
if (branch) {
if (configuration.repository.name === name && configuration.repository.organization === organization && configuration.repository.branch === branch) {
return r
}
} else {
if (configuration.repository.name === name && configuration.repository.organization === organization) {
return r
}
}
return null
})
if (found) {
return JSON.parse(found.Spec.Labels.configuration)
} else {
reply.code(500).send({ message: 'No configuration found.' })
}
})
}

View File

@@ -1,63 +0,0 @@
const { docker } = require('../../../libs/docker')
const Deployment = require('../../../models/Deployment')
const ServerLog = require('../../../models/Logs/Server')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
try {
const latestDeployments = await Deployment.aggregate([
{
$sort: { createdAt: -1 }
},
{
$group:
{
_id: {
repoId: '$repoId',
branch: '$branch'
},
createdAt: { $last: '$createdAt' },
progress: { $first: '$progress' }
}
}
])
const serverLogs = await ServerLog.find()
const services = await docker.engine.listServices()
let applications = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' && r.Spec.Labels.configuration)
let databases = services.filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'database' && r.Spec.Labels.configuration)
applications = applications.map(r => {
if (JSON.parse(r.Spec.Labels.configuration)) {
const configuration = JSON.parse(r.Spec.Labels.configuration)
const status = latestDeployments.find(l => configuration.repository.id === l._id.repoId && configuration.repository.branch === l._id.branch)
if (status && status.progress) r.progress = status.progress
r.Spec.Labels.configuration = configuration
return r
}
return {}
})
databases = databases.map(r => {
const configuration = r.Spec.Labels.configuration ? JSON.parse(r.Spec.Labels.configuration) : null
r.Spec.Labels.configuration = configuration
return r
})
applications = [...new Map(applications.map(item => [item.Spec.Labels.configuration.publish.domain + item.Spec.Labels.configuration.publish.path, item])).values()]
return {
serverLogs,
applications: {
deployed: applications
},
databases: {
deployed: databases
}
}
} catch (error) {
if (error.code === 'ENOENT' && error.errno === -2) {
throw new Error(`Docker service unavailable at ${error.address}.`)
} else {
throw { error, type: 'server' }
}
}
})
}

View File

@@ -1,177 +0,0 @@
const yaml = require('js-yaml')
const fs = require('fs').promises
const cuid = require('cuid')
const { docker } = require('../../../libs/docker')
const { execShellAsync } = require('../../../libs/common')
const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator')
const generator = require('generate-password')
function getUniq () {
return uniqueNamesGenerator({ dictionaries: [adjectives, animals, colors], length: 2 })
}
module.exports = async function (fastify) {
fastify.get('/:deployId', async (request, reply) => {
const { deployId } = request.params
try {
const database = (await docker.engine.listServices()).find(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'database' && JSON.parse(r.Spec.Labels.configuration).general.deployId === deployId)
if (database) {
const jsonEnvs = {}
for (const d of database.Spec.TaskTemplate.ContainerSpec.Env) {
const s = d.split('=')
jsonEnvs[s[0]] = s[1]
}
const payload = {
config: JSON.parse(database.Spec.Labels.configuration),
envs: jsonEnvs
}
reply.code(200).send(payload)
} else {
throw new Error()
}
} catch (error) {
throw new Error('No database found?')
}
})
const postSchema = {
body: {
type: 'object',
properties: {
type: { type: 'string', enum: ['mongodb', 'postgresql', 'mysql', 'couchdb'] }
},
required: ['type']
}
}
fastify.post('/deploy', { schema: postSchema }, async (request, reply) => {
try {
let { type, defaultDatabaseName } = request.body
const passwords = generator.generateMultiple(2, {
length: 24,
numbers: true,
strict: true
})
const usernames = generator.generateMultiple(2, {
length: 10,
numbers: true,
strict: true
})
// TODO: Query for existing db with the same name
const nickname = getUniq()
if (!defaultDatabaseName) defaultDatabaseName = nickname
reply.code(201).send({ message: 'Deploying.' })
// TODO: Persistent volume, custom inputs
const deployId = cuid()
const configuration = {
general: {
workdir: `/tmp/${deployId}`,
deployId,
nickname,
type
},
database: {
usernames,
passwords,
defaultDatabaseName
},
deploy: {
name: nickname
}
}
let generateEnvs = {}
let image = null
let volume = null
if (type === 'mongodb') {
generateEnvs = {
MONGODB_ROOT_PASSWORD: passwords[0],
MONGODB_USERNAME: usernames[0],
MONGODB_PASSWORD: passwords[1],
MONGODB_DATABASE: defaultDatabaseName
}
image = 'bitnami/mongodb:4.4'
volume = `${configuration.general.deployId}-${type}-data:/bitnami/mongodb`
} else if (type === 'postgresql') {
generateEnvs = {
POSTGRESQL_PASSWORD: passwords[0],
POSTGRESQL_USERNAME: usernames[0],
POSTGRESQL_DATABASE: defaultDatabaseName
}
image = 'bitnami/postgresql:13.2.0'
volume = `${configuration.general.deployId}-${type}-data:/bitnami/postgresql`
} else if (type === 'couchdb') {
generateEnvs = {
COUCHDB_PASSWORD: passwords[0],
COUCHDB_USER: usernames[0]
}
image = 'bitnami/couchdb:3'
volume = `${configuration.general.deployId}-${type}-data:/bitnami/couchdb`
} else if (type === 'mysql') {
generateEnvs = {
MYSQL_ROOT_PASSWORD: passwords[0],
MYSQL_ROOT_USER: usernames[0],
MYSQL_USER: usernames[1],
MYSQL_PASSWORD: passwords[1],
MYSQL_DATABASE: defaultDatabaseName
}
image = 'bitnami/mysql:8.0'
volume = `${configuration.general.deployId}-${type}-data:/bitnami/mysql/data`
}
const stack = {
version: '3.8',
services: {
[configuration.general.deployId]: {
image,
networks: [`${docker.network}`],
environment: generateEnvs,
volumes: [volume],
deploy: {
replicas: 1,
update_config: {
parallelism: 0,
delay: '10s',
order: 'start-first'
},
rollback_config: {
parallelism: 0,
delay: '10s',
order: 'start-first'
},
labels: [
'managedBy=coolify',
'type=database',
'configuration=' + JSON.stringify(configuration)
]
}
}
},
networks: {
[`${docker.network}`]: {
external: true
}
},
volumes: {
[`${configuration.general.deployId}-${type}-data`]: {
external: true
}
}
}
await execShellAsync(`mkdir -p ${configuration.general.workdir}`)
await fs.writeFile(`${configuration.general.workdir}/stack.yml`, yaml.dump(stack))
await execShellAsync(
`cat ${configuration.general.workdir}/stack.yml | docker stack deploy -c - ${configuration.general.deployId}`
)
} catch (error) {
throw { error, type: 'server' }
}
})
fastify.delete('/:dbName', async (request, reply) => {
const { dbName } = request.params
await execShellAsync(`docker stack rm ${dbName}`)
reply.code(200).send({})
})
}

View File

@@ -1,121 +0,0 @@
const axios = require('axios')
const User = require('../../../models/User')
const Settings = require('../../../models/Settings')
const cuid = require('cuid')
const mongoose = require('mongoose')
const jwt = require('jsonwebtoken')
module.exports = async function (fastify) {
const githubCodeSchema = {
schema: {
querystring: {
type: 'object',
properties: {
code: { type: 'string' }
},
required: ['code']
}
}
}
fastify.get('/app', { schema: githubCodeSchema }, async (request, reply) => {
const { code } = request.query
try {
const { data } = await axios({
method: 'post',
url: `https://github.com/login/oauth/access_token?client_id=${fastify.config.VITE_GITHUB_APP_CLIENTID}&client_secret=${fastify.config.GITHUB_APP_CLIENT_SECRET}&code=${code}`,
headers: {
accept: 'application/json'
}
})
const token = data.access_token
const githubAxios = axios.create({
baseURL: 'https://api.github.com'
})
githubAxios.defaults.headers.common.Accept = 'Application/json'
githubAxios.defaults.headers.common.Authorization = `token ${token}`
try {
let uid = cuid()
const { avatar_url } = (await githubAxios.get('/user')).data // eslint-disable-line
const email = (await githubAxios.get('/user/emails')).data.filter(
(e) => e.primary
)[0].email
const settings = await Settings.findOne({ applicationName: 'coolify' })
const registeredUsers = await User.find().countDocuments()
const foundUser = await User.findOne({ email })
if (foundUser) {
await User.findOneAndUpdate(
{ email },
{ avatar: avatar_url },
{ upsert: true, new: true }
)
uid = foundUser.uid
} else {
if (registeredUsers === 0) {
const newUser = new User({
_id: new mongoose.Types.ObjectId(),
email,
avatar: avatar_url,
uid
})
try {
await newUser.save()
} catch (e) {
console.log(e)
reply.code(500).send({ success: false, error: e })
return
}
} else {
if (!settings && registeredUsers > 0) {
reply.code(500).send('Registration disabled, enable it in settings.')
} else {
if (!settings.allowRegistration) {
reply.code(500).send('You are not allowed here!')
} else {
const newUser = new User({
_id: new mongoose.Types.ObjectId(),
email,
avatar: avatar_url,
uid
})
try {
await newUser.save()
} catch (e) {
console.log(e)
reply.code(500).send({ success: false, error: e })
return
}
}
}
}
}
const jwtToken = jwt.sign({}, fastify.config.JWT_SIGN_KEY, {
expiresIn: 15778800,
algorithm: 'HS256',
audience: 'coolLabs',
issuer: 'coolLabs',
jwtid: uid,
subject: `User:${uid}`,
notBefore: -1000
})
reply
.code(200)
.redirect(
302,
`/api/v1/login/github/success?jwtToken=${jwtToken}&ghToken=${token}`
)
} catch (e) {
console.log(e)
reply.code(500).send({ success: false, error: e })
return
}
} catch (error) {
console.log(error)
reply.code(500).send({ success: false, error: error.message })
}
})
fastify.get('/success', async (request, reply) => {
return reply.sendFile('bye.html')
})
}

View File

@@ -1,14 +0,0 @@
const Server = require('../../../models/Logs/Server')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
try {
const serverLogs = await Server.find().select('-_id -__v')
// TODO: Should do better
return {
serverLogs
}
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,44 +0,0 @@
const Settings = require('../../../models/Settings')
module.exports = async function (fastify) {
const applicationName = 'coolify'
const postSchema = {
body: {
type: 'object',
properties: {
allowRegistration: { type: 'boolean' }
},
required: ['allowRegistration']
}
}
fastify.get('/', async (request, reply) => {
try {
let settings = await Settings.findOne({ applicationName }).select('-_id -__v')
// TODO: Should do better
if (!settings) {
settings = {
applicationName,
allowRegistration: false
}
}
return {
settings
}
} catch (error) {
throw { error, type: 'server' }
}
})
fastify.post('/', { schema: postSchema }, async (request, reply) => {
try {
const settings = await Settings.findOneAndUpdate(
{ applicationName },
{ applicationName, ...request.body },
{ upsert: true, new: true }
).select('-_id -__v')
reply.code(201).send({ settings })
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,5 +0,0 @@
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
reply.code(200).send('NO')
})
}

View File

@@ -1,12 +0,0 @@
const { execShellAsync } = require('../../../libs/common')
const { saveServerLog } = require('../../../libs/logging')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
const upgradeP1 = await execShellAsync('bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p1.sh)"')
await saveServerLog({ event: upgradeP1, type: 'UPGRADE-P-1' })
reply.code(200).send('I\'m trying, okay?')
const upgradeP2 = await execShellAsync('docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -u root coolify bash -c "$(curl -fsSL https://get.coollabs.io/coolify/upgrade-p2.sh)"')
await saveServerLog({ event: upgradeP2, type: 'UPGRADE-P-2' })
})
}

View File

@@ -1,20 +0,0 @@
const User = require('../../models/User')
const jwt = require('jsonwebtoken')
module.exports = async function (fastify) {
fastify.get('/', async (request, reply) => {
try {
const { authorization } = request.headers
if (!authorization) {
reply.code(401).send({})
return
}
const token = authorization.split(' ')[1]
const verify = jwt.verify(token, fastify.config.JWT_SIGN_KEY)
const found = await User.findOne({ uid: verify.jti })
found ? reply.code(200).send({}) : reply.code(401).send({})
} catch (error) {
reply.code(401).send({})
}
})
}

View File

@@ -1,99 +0,0 @@
const crypto = require('crypto')
const { cleanupTmp } = require('../../../libs/common')
const Deployment = require('../../../models/Deployment')
const { queueAndBuild } = require('../../../libs/applications')
const { setDefaultConfiguration, precheckDeployment } = require('../../../libs/applications/configuration')
const { docker } = require('../../../libs/docker')
const cloneRepository = require('../../../libs/applications/github/cloneRepository')
module.exports = async function (fastify) {
// TODO: Add this to fastify plugin
const postSchema = {
body: {
type: 'object',
properties: {
ref: { type: 'string' },
repository: {
type: 'object',
properties: {
id: { type: 'number' },
full_name: { type: 'string' }
},
required: ['id', 'full_name']
},
installation: {
type: 'object',
properties: {
id: { type: 'number' }
},
required: ['id']
}
},
required: ['ref', 'repository', 'installation']
}
}
fastify.post('/', { schema: postSchema }, async (request, reply) => {
const hmac = crypto.createHmac('sha256', fastify.config.GITHUP_APP_WEBHOOK_SECRET)
const digest = Buffer.from('sha256=' + hmac.update(JSON.stringify(request.body)).digest('hex'), 'utf8')
const checksum = Buffer.from(request.headers['x-hub-signature-256'], 'utf8')
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
reply.code(500).send({ error: 'Invalid request' })
return
}
if (request.headers['x-github-event'] !== 'push') {
reply.code(500).send({ error: 'Not a push event.' })
return
}
try {
const services = (await docker.engine.listServices()).filter(r => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application')
let configuration = services.find(r => {
if (request.body.ref.startsWith('refs')) {
const branch = request.body.ref.split('/')[2]
if (
JSON.parse(r.Spec.Labels.configuration).repository.id === request.body.repository.id &&
JSON.parse(r.Spec.Labels.configuration).repository.branch === branch
) {
return r
}
}
return null
})
if (!configuration) {
reply.code(500).send({ error: 'No configuration found.' })
return
}
configuration = setDefaultConfiguration(JSON.parse(configuration.Spec.Labels.configuration))
await cloneRepository(configuration)
const { foundService, imageChanged, configChanged, forceUpdate } = await precheckDeployment({ services, configuration })
if (foundService && !forceUpdate && !imageChanged && !configChanged) {
cleanupTmp(configuration.general.workdir)
reply.code(500).send({ message: 'Nothing changed, no need to redeploy.' })
return
}
const alreadyQueued = await Deployment.find({
repoId: configuration.repository.id,
branch: configuration.repository.branch,
organization: configuration.repository.organization,
name: configuration.repository.name,
domain: configuration.publish.domain,
progress: { $in: ['queued', 'inprogress'] }
})
if (alreadyQueued.length > 0) {
reply.code(200).send({ message: 'Already in the queue.' })
return
}
queueAndBuild(configuration, imageChanged)
reply.code(201).send({ message: 'Deployment queued.', nickname: configuration.general.nickname, name: configuration.build.container.name })
} catch (error) {
throw { error, type: 'server' }
}
})
}

View File

@@ -1,49 +0,0 @@
const schema = {
type: 'object',
required: [
'DOMAIN',
'EMAIL',
'VITE_GITHUB_APP_CLIENTID',
'GITHUB_APP_CLIENT_SECRET',
'GITHUB_APP_PRIVATE_KEY',
'GITHUP_APP_WEBHOOK_SECRET',
'JWT_SIGN_KEY',
'SECRETS_ENCRYPTION_KEY'
],
properties: {
DOMAIN: {
type: 'string'
},
EMAIL: {
type: 'string'
},
VITE_GITHUB_APP_CLIENTID: {
type: 'string'
},
GITHUB_APP_CLIENT_SECRET: {
type: 'string'
},
GITHUB_APP_PRIVATE_KEY: {
type: 'string'
},
GITHUP_APP_WEBHOOK_SECRET: {
type: 'string'
},
JWT_SIGN_KEY: {
type: 'string'
},
DOCKER_ENGINE: {
type: 'string',
default: '/var/run/docker.sock'
},
DOCKER_NETWORK: {
type: 'string',
default: 'coollabs'
},
SECRETS_ENCRYPTION_KEY: {
type: 'string'
}
}
}
module.exports = { schema }

View File

@@ -1,116 +0,0 @@
require('dotenv').config()
const fs = require('fs')
const util = require('util')
const { saveServerLog } = require('./libs/logging')
const { execShellAsync } = require('./libs/common')
const { purgeImagesContainers, cleanupStuckedDeploymentsInDB } = require('./libs/applications/cleanup')
const Deployment = require('./models/Deployment')
const fastify = require('fastify')({
logger: { level: 'error' }
})
const mongoose = require('mongoose')
const path = require('path')
const { schema } = require('./schema')
process.on('unhandledRejection', (reason, p) => {
console.log(reason)
console.log(p)
})
fastify.register(require('fastify-env'), {
schema,
dotenv: true
})
if (process.env.NODE_ENV === 'production') {
fastify.register(require('fastify-static'), {
root: path.join(__dirname, '../dist/')
})
fastify.setNotFoundHandler(function (request, reply) {
reply.sendFile('index.html')
})
} else {
fastify.register(require('fastify-static'), {
root: path.join(__dirname, '../public/')
})
}
fastify.register(require('./app'), { prefix: '/api/v1' })
fastify.setErrorHandler(async (error, request, reply) => {
if (error.statusCode) {
reply.status(error.statusCode).send({ message: error.message } || { message: 'Something is NOT okay. Are you okay?' })
} else {
reply.status(500).send({ message: error.message } || { message: 'Something is NOT okay. Are you okay?' })
}
try {
await saveServerLog({ event: error })
} catch (error) {
//
}
})
if (process.env.NODE_ENV === 'production') {
mongoose.connect(
`mongodb://${process.env.MONGODB_USER}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DB}?authSource=${process.env.MONGODB_DB}&readPreference=primary&ssl=false`,
{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false }
)
} else {
mongoose.connect(
'mongodb://localhost:27017/coolify?&readPreference=primary&ssl=false',
{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false }
)
}
mongoose.connection.on(
'error',
console.error.bind(console, 'connection error:')
)
mongoose.connection.once('open', async function () {
if (process.env.NODE_ENV === 'production') {
fastify.listen(3000, '0.0.0.0')
console.log('Coolify API is up and running in production.')
} else {
const logFile = fs.createWriteStream('api/development/console.log', { flags: 'w' })
const logStdout = process.stdout
console.log = function (d) {
logFile.write(`[INFO]: ${util.format(d)}\n`)
logStdout.write(util.format(d) + '\n')
}
console.error = function (d) {
logFile.write(`[ERROR]: ${util.format(d)}\n`)
logStdout.write(util.format(d) + '\n')
}
console.warn = function (d) {
logFile.write(`[WARN]: ${util.format(d)}\n`)
logStdout.write(util.format(d) + '\n')
}
fastify.listen(3001)
console.log('Coolify API is up and running in development.')
}
// On start cleanup inprogress/queued deployments.
try {
await cleanupStuckedDeploymentsInDB()
} catch (error) {
// Could not cleanup DB 🤔
}
try {
// Doing because I do not want to prune these images. Prune skip coolify-reserve labeled images.
const basicImages = ['nginx:stable-alpine', 'node:lts', 'ubuntu:20.04']
for (const image of basicImages) {
await execShellAsync(`echo "FROM ${image}" | docker build --label coolify-reserve=true -t ${image} -`)
}
} catch (error) {
console.log('Could not pull some basic images from Docker Hub.')
console.log(error)
}
try {
await purgeImagesContainers()
} catch (error) {
console.log('Could not purge containers/images.')
console.log(error)
}
})

View File

@@ -0,0 +1 @@
nohup docker build -t coollabsio/prisma-engine:<arm64/amd64> --push . &

11
data/docker/daemon.json Normal file
View File

@@ -0,0 +1,11 @@
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
},
"features": {
"buildkit": true
},
"live-restore": true
}

View File

@@ -0,0 +1,6 @@
FROM haproxytech/haproxy-alpine:2.5
RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe
COPY data/haproxy/haproxy.cfg-http.template /usr/local/etc/haproxy/haproxy.cfg
COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl
COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem

View File

@@ -0,0 +1,6 @@
FROM haproxytech/haproxy-alpine:2.5
RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe
COPY data/haproxy/haproxy.cfg-tcp.template /usr/local/etc/haproxy/haproxy.cfg
COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl
COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem

6
data/haproxy.Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
FROM haproxytech/haproxy-alpine:2.5
RUN mkdir -p /usr/local/etc/haproxy/ssl /usr/local/etc/haproxy/maps /usr/local/etc/haproxy/spoe
COPY data/haproxy/haproxy.cfg.template /usr/local/etc/haproxy/haproxy.cfg
COPY data/haproxy/dataplaneapi.hcl /usr/local/etc/haproxy/dataplaneapi.hcl
COPY data/haproxy/ssl/default.pem /usr/local/etc/haproxy/ssl/default.pem

View File

@@ -0,0 +1,29 @@
config_version = 2
name = "easy_gar"
mode = "single"
status = "null"
dataplaneapi {
host = "0.0.0.0"
port = 5555
transaction {
transaction_dir = "/tmp/haproxy"
}
advertised {
api_address = ""
api_port = 0
}
}
haproxy {
config_file = "/usr/local/etc/haproxy/haproxy.cfg"
haproxy_bin = "/usr/local/sbin/haproxy"
reload {
reload_delay = 2
reload_cmd = "kill -HUP 1"
restart_cmd = "kill -SIGUSR2 1"
}
}

View File

@@ -0,0 +1,19 @@
global
log stdout format raw local0 debug
defaults
mode http
log global
timeout http-request 120s
timeout connect 20s
timeout client 120s
timeout server 120s
frontend "${APP}"
mode http
bind *:"${PORT}" name "${APP}"
default_backend "${APP}"
backend "${APP}"
mode http
server "${APP}" "${APP}":"${PRIVATE_PORT}" check

View File

@@ -0,0 +1,15 @@
global
log stdout format raw local0 debug
defaults
mode tcp
log global
frontend "${APP}"
mode tcp
bind *:"${PORT}" name "${APP}"
default_backend "${APP}"
backend "${APP}"
mode tcp
server "${APP}" "${APP}":"${PRIVATE_PORT}" check

View File

@@ -0,0 +1,38 @@
global
stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners
log stdout format raw local0 debug
defaults
mode http
log global
timeout http-request 120s
timeout connect 20s
timeout client 120s
timeout server 120s
userlist haproxy-dataplaneapi
user admin insecure-password "${HAPROXY_PASSWORD}"
frontend http
mode http
bind :80
bind :443 ssl crt /usr/local/etc/haproxy/ssl/ alpn h2,http/1.1
acl is_certbot path_beg /.well-known/acme-challenge/
use_backend backend-certbot if is_certbot
use_backend %[req.hdr(host),lower]
frontend stats
bind *:8404
stats enable
stats uri /
stats refresh 5s
stats admin if TRUE
stats auth "${HAPROXY_USERNAME}:${HAPROXY_PASSWORD}"
backend backend-certbot
mode http
server certbot host.docker.internal:9080
program api
command /usr/bin/dataplaneapi -f /usr/local/etc/haproxy/dataplaneapi.hcl --userlist haproxy-dataplaneapi
no option start-on-reload

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIFETCCAvkCFE/5JtU5geT5hOjFuQPiLgCYHwsOMA0GCSqGSIb3DQEBCwUAMEUx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjExMDExMDkwNzQ1WhcNMzExMDA5MDkw
NzQ1WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE
CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEArEZDhvc3ew2Gb8pvJlUrh5x+L5iqNxDYU3cOcOgeELCmOyAS
cH+/1xrsHQI05xWPpz6VAja2NKl4OP90getPPkiQV1xAg5/gsOsRL8Pi/MwvQKfZ
ObyW3t+sfFb1K3sVnm8bgk5F9OIVyAtzAx+Y53muEJsHOHpaEidnwbY2VE0zQB/G
DBQovrMefAwmH4RPqFor6NzFMKVRi33pQjYmcfCVFZylrDeCn8T7llV0lrnWqv6z
sGKfL3E4nHvyh/RsGNOXy+XQMxB9SA3j6hFTNtgQIPO/lxptz/+BLZoUt48nHZtr
sc5j+3sn8c1O9e6MjI/1q8lvZsk7ZsWCGSwCOvJ9LnxCWOEQUUfqIvGLsk7NJQgf
IkodZH9sW5Sjlro21+WBf3nvqlZ8g7r6K1RJOA8AtUiCaN/+o65t86WkwCSwQXcm
+nArcwddOx2HN9sFrjJ59N1eYEDGmyK3BdppYuVXay705PmxotR1hCBvnXOb34dn
gZxsxFTohr97JvEdNtGSNz4USyZPjgIMF/Gu8ruh0gQ1byhmayRqMGEqMAh58Lvb
3HYsd3Bf+LB9PpaXLAdKzsTZ8a28zyDYo8a70h7iBRxhmFwa+Df+pSmUEdzhejfx
7jEslhBQSQDmllaHrHc1G6H/w/u+04vi1joaLeLEGQclinKLeU88s9j3zzUCAwEA
ATANBgkqhkiG9w0BAQsFAAOCAgEAGQED96wBGzbMUlk9mIvZeLerzEAB3YfgfAYa
EAi79QHxM8UX06xmA2xtGvJSvlU8Xods9vxpBmIUnbDRTIAHNDApT19+vPg/iSfQ
1J9Fo4b5kjmWL6SalEdYcxqH9V/QndHta4MXP91u/ZsJ/exwDTZFatXsfGkPjUmN
Xp+Ip6iQg7+kV3JpRnMSbevj2Oujs7qTAdQedH38ZTNS0AaM5gvZyQkccCTKNBQ4
3O8MhCau7U0EUirndqsQXa0D3o78FpKztLNXSM7919jU2y36kMrWXfArfrBKHJ9b
nZeO7nkbHgvmVS8NTg9pR7L7u+YXTa2p1H2ZnpMQvruV7iL/Pb1H2N68UdvnQScL
sgacGSzM6b6PVdWRbECiuzC0UyWLZo/LoU3DQFGoiDQ4e/B3+TMrvgFI0CnpAQ4w
qiaVFJlRQeF4GaS4qHsN28OBliFATB3TXONFnz1aVkQlEHuh2+JbuL1b1lxvlX5t
gBbu/GgAcP4Uy2z4PoDmempAvNi2kCcLB98m+jbFSMSB3nkrdj6MzyN7kW9bhk3T
ClimxDmc23seprwLcxJUPP5q+HRB1VLKXLwIYxu+Up3g29d4k1Iy9nUUP9lITLTk
blJxZ2BPuQqTLzyqmAEWa1HxljFC1b7oMp9a98PbxC3MxUggM7zx/rgXWxM8osib
uwSZmw0=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEArEZDhvc3ew2Gb8pvJlUrh5x+L5iqNxDYU3cOcOgeELCmOyAS
cH+/1xrsHQI05xWPpz6VAja2NKl4OP90getPPkiQV1xAg5/gsOsRL8Pi/MwvQKfZ
ObyW3t+sfFb1K3sVnm8bgk5F9OIVyAtzAx+Y53muEJsHOHpaEidnwbY2VE0zQB/G
DBQovrMefAwmH4RPqFor6NzFMKVRi33pQjYmcfCVFZylrDeCn8T7llV0lrnWqv6z
sGKfL3E4nHvyh/RsGNOXy+XQMxB9SA3j6hFTNtgQIPO/lxptz/+BLZoUt48nHZtr
sc5j+3sn8c1O9e6MjI/1q8lvZsk7ZsWCGSwCOvJ9LnxCWOEQUUfqIvGLsk7NJQgf
IkodZH9sW5Sjlro21+WBf3nvqlZ8g7r6K1RJOA8AtUiCaN/+o65t86WkwCSwQXcm
+nArcwddOx2HN9sFrjJ59N1eYEDGmyK3BdppYuVXay705PmxotR1hCBvnXOb34dn
gZxsxFTohr97JvEdNtGSNz4USyZPjgIMF/Gu8ruh0gQ1byhmayRqMGEqMAh58Lvb
3HYsd3Bf+LB9PpaXLAdKzsTZ8a28zyDYo8a70h7iBRxhmFwa+Df+pSmUEdzhejfx
7jEslhBQSQDmllaHrHc1G6H/w/u+04vi1joaLeLEGQclinKLeU88s9j3zzUCAwEA
AQKCAgEAm1/z33Jwk4crTQAjJ0uBqxm1pW/ndSq4MO8cEzEGjL8F7iWK+/P8LiGV
+sPWuuRzX7/N3OVDiFOgnqeniNWV7vK7XE9T0GMN4ALiyVW/D4mIxKOeA7jXycOq
aap0DPdCFFbZVLkL10Vhp77LyHFjEsJn/4oTBRk0y1LG/as9bOMD6j29/X7hEL20
LOU4LQzEW26YU7lqD+nKlijFjHYSTolRrOBPe/fE1BxxXLFOKfMKbcaygc8xCzTu
fhQ8Nep45BtSuQ9Yq/WfSLFecemWR8yvH0k37yxjBknHVD23maZ+/PEEPKWM/2+g
IzGsmZrBILVmOb2/v9CWxqY0JEfQ6aU/nLW1ZiXSOIPmKEooK/hPVxFIyQ1yET4G
kQZ5RroY/QDrI14ms8P0iDzZ8K3EFKUyjiBbc83Mb0YIZ4hKd76gioOUIPeEQB+y
QLZ8Cb9YS3V8uIOJg+F4xlpJSePAZphfSxRLojSiKUeCs8gNUxGz0zwiMNf1p76F
8CaLgvSwT/cgQjWitMeeE1Ha+8lY8VzESmd10gPk2uES/qdrmMhwFwovPqqrtMqj
kMrFKNy7Crka6me3dhKEtryRTk5ho2IS/VCy/eXQ7lUW8Cl4uFxmjpHYSJMqDWvC
vu1p3/B1psSZIy2V2M9QqwZCysHqvGJMOCvYmnc6T62+kDRKQ7ECggEBAOS/1ptA
75OBAsHLovkspiCvn3gb/VTvH6LOvxYTohjr5iBeX137vg0aR1rg0jwcdf8EEJYw
4YxOid7KmV7O25ujzduQgwpVgujnJAeBLeLDC5dVbq3PQah61AvR2O/7t+Ls3oxi
cWh/OHC6SeZ/n406cxSCCUpVwtgHTaNFzaSmpDdEOSbjvXjQQjiRsG7j/1u64riq
RlJ/hIUlcys0g94yeN/5lPaNfsq0+vTSAYuTVVXVbEntwWcZVZxnQJviZVgJ99zM
RzE3sprvvr+I5QQ4FRMn0W9U7gblSJd5FGEL8gye4SRd+LxoUL4DR6pfuwd0vlXA
g+dgiOKoHm2Bb8cCggEBAMDMHMNR6uipdMivPjBTlklnaYd9SY3c5x65yNtx4CNh
rXyvy/6YvME7PPnKQZ8TQ4DkbVDUCAF7wnyAJJ7eWMav3bNlqWWjzaBvQz4Fn0XG
/1W5R1CoJ9DW5FY3f9efJzQTmfn6dIlCx1gW7XfVBZQqI1LORMWUYenk0KAvjlg2
UHYYl/BT1RhtYyzOJHto1PaUvCNDiOiDWAkTpLigYm7hGgVmcSwbo4F54SNUHdV7
yz3CorCM4VsEYYSL80WHYxf/Zc+mcIDoWOdog0iEeK/Zu++yG5lPRxC1862GmsZA
J06BMqX+NVGOfiGcVaGH+SZJXeFcrr7F8ZWp6y38QSMCggEAJwzo4hAv1gqMIfFV
nRwWMDZLDwIYOUupJu4MiQRJA+AhpRz3QuAbDbmSvNzshv6E1kgnXLxzhLRTrQkB
LcI6k1NfbUA6XqVCd+gdqnpPDwslC2y2PE3Jc62kTXBBjJZ4SfEN/QFBQwmU5Qmo
XAUlg8KaqsGYPGxvmtmEU38zIAyitByddRoj2mATLf0RFZ0ulsZMtiG7Z5IFWYWP
J60LZf9Py0ycNYrqPkivHuRLBzzbsI+CsQw5nBQjHVQzH2mCy4jIG5V0Ad70Sqbq
9V+1WQcJ8f82Lb9d8ydpQRKWfArCA42L+d1g/SkBv65nqZo2H4u6goEfA3zjYW45
44/ZOQKCAQB440MhwYqe6ioc76z51l+ElUAZQZjOR/XvUSS9XHDjHosOhJhPgmvQ
aZl5MrXkzcpk1lYo+Vovu+8d66eKqfZWVs2XgCYwYf48G6e5CwNsWDOgB7XMwDN/
Ak9YNCKIC/Yj9Cp3EPDjZCjkdjPeEIcX+Tf+4vFCRiEC7INX/ZmufBgFhLQ4cAhM
8cHexT8g1oG6P1acces1h626u0NstLwjtCeBvVM3CfmC5O4jHco7Iw00I4epVhyz
2lJfLvWR4itjT7QB+OXQHmAocWLoJJAcC1WJHU+q2IfB1aT+aElCB9XdpqsgY/4A
rm0uG/2hdEXoGNaxyVCUtD8fzdR2GBarAoIBACCYXXREMYb6i1TbR5Q2LvVQUPsO
Hgnbr+PLmx93rfUzDcr5r+cJgryjYQDKJTRleDJhg80M3RYOq+IOdl6yxOmRATmJ
ZDgwRVD1F6VFxBJePcAW30FI5CoBogsHaZQDKGsopEaDRLK5E3QHUVG5qj323RdI
Unf1++wI4nw+qwsVf1gSTcAdzq29v3NIWUyvvrmTNO4MxFTt0/lqkCsdT/2EFQDB
/yQ1HCtQQjXE1xlYh0BnMZp9+4FmrlMC9Oj5H0dDSWmInPION0ft8/SjBj4TQ5Qi
2DUo1WOWQnVR8Bxz0B8McXS+dOmgLe8ws4/ez7DoEVqHTgirKqBg5qRFQKw=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,10 @@
FROM rust:1.58.1-alpine3.14 as prisma
WORKDIR /prisma
ENV RUSTFLAGS="-C target-feature=-crt-static"
RUN apk --no-cache add openssl direnv git musl-dev openssl-dev build-base perl protoc
RUN git clone --depth=1 --branch=3.11.x https://github.com/prisma/prisma-engines.git /prisma
RUN cargo build --release
FROM alpine
WORKDIR /prisma-engines
COPY --from=prisma /prisma/target/release/query-engine /prisma/target/release/migration-engine /prisma/target/release/introspection-engine /prisma/target/release/prisma-fmt /prisma-engines/

0
db/.gitkeep Normal file
View File

18
docker-compose-dev.yaml Normal file
View File

@@ -0,0 +1,18 @@
version: '3.8'
services:
redis:
image: redis:6.2-alpine
container_name: coolify-redis
networks:
- coolify-infra
ports:
- target: 6379
published: 6379
protocol: tcp
mode: host
networks:
coolify-infra:
attachable: true
name: coolify-infra

View File

@@ -0,0 +1,23 @@
version: '3.8'
services:
haproxy:
image: coollabsio/coolify-haproxy-alpine:latest
container_name: coolify-haproxy
extra_hosts:
- 'host.docker.internal:host-gateway'
networks:
- coolify
volumes:
- './data/haproxy/:/usr/local/etc/haproxy/'
ports:
- '80:80'
- '443:443'
- '8404:8404'
- '5555:5555'
- '3306:3306'
networks:
coolify:
attachable: true
name: coolify

41
docker-compose.yaml Normal file
View File

@@ -0,0 +1,41 @@
version: '3.8'
services:
coolify:
image: coollabsio/coolify:${TAG:-latest}
restart: always
container_name: coolify
ports:
- target: 3000
published: 3000
protocol: tcp
mode: host
volumes:
- 'coolify-db:/app/db'
- 'coolify-ssl-certs:/app/ssl'
- 'coolify-letsencrypt:/etc/letsencrypt'
- '/var/run/docker.sock:/var/run/docker.sock'
env_file:
- '.env'
networks:
- coolify-infra
depends_on: ['redis']
redis:
image: redis:6.2-alpine
restart: always
container_name: coolify-redis
networks:
- coolify-infra
networks:
coolify-infra:
attachable: true
name: coolify-infra
volumes:
coolify-db:
name: coolify-db
coolify-ssl-certs:
name: coolify-ssl-certs
coolify-letsencrypt:
name: coolify-letsencrypt

View File

@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.png" />
<link rel="preload" as="image" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>coolify: Heroku & Netlify alternative</title>
<link rel="dns-prefetch" href="https://cdn.coollabs.io/" />
<link rel="preconnect" href="https://cdn.coollabs.io/" crossorigin="" />
<link rel="stylesheet" href="https://cdn.coollabs.io/fonts/montserrat/montserrat.css" />
<link rel="stylesheet" href="https://cdn.coollabs.io/css/microtip-0.2.2.min.css" />
</head>
<body>
<script type="module" src="/src/index.js"></script>
</body>
</html>

View File

@@ -1,88 +0,0 @@
#!/bin/bash
preTasks() {
echo '
##############################
#### Pulling Git Updates #####
##############################'
GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git pull
if [ $? -ne 0 ]; then
echo '
####################################
#### Ooops something not okay! #####
####################################'
exit 1
fi
echo '
##############################
#### Building Base Image #####
##############################'
docker build --label coolify-reserve=true -t coolify-base -f install/Dockerfile-base .
if [ $? -ne 0 ]; then
echo '
####################################
#### Ooops something not okay! #####
####################################'
exit 1
fi
echo '
##################################
#### Checking configuration. #####
##################################'
docker run --rm -w /usr/src/app coolify-base node install/install.js --check
if [ $? -ne 0 ]; then
echo '
##################################
#### Missing configuration ! #####
##################################'
exit 1
fi
}
case "$1" in
"all")
preTasks
echo '
#################################
#### Rebuilding everything. #####
#################################'
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify:/data/coolify -u root -w /usr/src/app coolify-base node install/install.js --type all
;;
"coolify")
preTasks
echo '
##############################
#### Rebuilding Coolify. #####
##############################'
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify:/data/coolify -u root -w /usr/src/app coolify-base node install/install.js --type coolify
;;
"proxy")
preTasks
echo '
############################
#### Rebuilding Proxy. #####
############################'
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify:/data/coolify -u root -w /usr/src/app coolify-base node install/install.js --type proxy
;;
"upgrade-phase-1")
preTasks
echo '
################################
#### Upgrading Coolify P1. #####
################################'
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify:/data/coolify -u root -w /usr/src/app coolify-base node install/install.js --type upgrade
;;
"upgrade-phase-2")
echo '
################################
#### Upgrading Coolify P2. #####
################################'
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify:/data/coolify -u root -w /usr/src/app coolify-base node install/update.js --type upgrade
;;
*)
exit 1
;;
esac

View File

@@ -1,5 +0,0 @@
FROM coolify-base
WORKDIR /usr/src/app
RUN pnpm build
CMD ["pnpm", "start"]
EXPOSE 3000

View File

@@ -1,19 +0,0 @@
FROM ubuntu:20.04 as binaries
RUN apt update && apt install -y curl gnupg2 ca-certificates
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
RUN echo 'deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable' >> /etc/apt/sources.list
RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o /usr/bin/envsubst
RUN chmod +x /usr/bin/envsubst
RUN apt update && apt install -y docker-ce-cli && apt clean all
FROM node:14 as modules
COPY --from=binaries /usr/bin/docker /usr/bin/docker
COPY --from=binaries /usr/bin/envsubst /usr/bin/envsubst
RUN curl -L https://pnpm.js.org/pnpm.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY ./package*.json .
RUN pnpm install
FROM modules
WORKDIR /usr/src/app
COPY . .

View File

@@ -1,24 +0,0 @@
FROM ubuntu:20.04 as binaries
LABEL coolify-preserve=true
RUN apt update && apt install -y curl gnupg2 ca-certificates
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
RUN echo 'deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable' >> /etc/apt/sources.list
RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o /usr/bin/envsubst
RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/bin/jq
RUN chmod +x /usr/bin/envsubst /usr/bin/jq
RUN apt update && apt install -y docker-ce-cli && apt clean all
FROM node:lts
WORKDIR /usr/src/app
LABEL coolify-preserve=true
COPY --from=binaries /usr/bin/docker /usr/bin/docker
COPY --from=binaries /usr/bin/envsubst /usr/bin/envsubst
COPY --from=binaries /usr/bin/jq /usr/bin/jq
COPY . .
RUN curl -f https://get.pnpm.io/v6.js | node - add --global pnpm@6
RUN pnpm install
RUN pnpm build
RUN rm -fr node_modules .pnpm-store
RUN pnpm install -P
CMD ["pnpm", "start"]
EXPOSE 3000

View File

@@ -1,10 +0,0 @@
Some of the files are here for backwards compatibility.
I will do things after 2 months:
- rm ./install.js and ./update.js
- rm ../install.sh
- rm ./Dockerfile-base
- rm ./obs
- rm ./check.js "No need to check env file. During installation, it is checked by the installer. If you change it between to upgrades: 🤷‍♂️"
- Rename Dockerfile-new to Dockerfile

View File

@@ -1,24 +0,0 @@
require('dotenv').config()
const fastify = require('fastify')()
const { schema } = require('../api/schema')
checkConfig().then(() => {
console.log('Config: OK')
}).catch((err) => {
console.log('Config: NOT OK')
console.error(err)
process.exit(1)
})
function checkConfig () {
return new Promise((resolve, reject) => {
fastify.register(require('fastify-env'), {
schema,
dotenv: true
})
.ready((err) => {
if (err) reject(err)
resolve()
})
})
}

View File

@@ -1,98 +0,0 @@
version: '3.8'
services:
proxy:
image: traefik:v2.3
hostname: coollabs-proxy
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
command:
- --api.insecure=false
- --api.dashboard=false
- --api.debug=false
- --log.level=ERROR
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=${DOCKER_NETWORK}
- --providers.docker.swarmModeRefreshSeconds=1s
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.httpchallenge=true
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.letsencrypt.acme.email=${EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/data/coolify/acme.json
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /data/coolify:/data/coolify
networks:
- ${DOCKER_NETWORK}
deploy:
update_config:
parallelism: 1
delay: 10s
order: start-first
replicas: 1
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=auth"
- "traefik.http.services.traefik.loadbalancer.server.port=80"
- "traefik.http.services.traefik.loadbalancer.server.port=443"
# Global redirect www to non-www
- "traefik.http.routers.www-catchall.rule=hostregexp(`{host:www.(.+)}`)"
- "traefik.http.routers.www-catchall.entrypoints=web"
- "traefik.http.routers.www-catchall.middlewares=redirect-www-to-nonwww"
- "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.regex=^http://(?:www\\.)?(.+)"
- "traefik.http.middlewares.redirect-www-to-nonwww.redirectregex.replacement=http://$$$${1}"
# Global redirect http to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.global-compress.compress=true"
coolify:
image: coolify
hostname: coollabs-coolify
env_file:
- .env
networks:
- ${DOCKER_NETWORK}
command: "yarn start"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
update_config:
parallelism: 1
delay: 10s
order: start-first
replicas: 1
labels:
- "traefik.enable=true"
- "traefik.http.routers.coolify.entrypoints=websecure"
- "traefik.http.routers.coolify.tls.certresolver=letsencrypt"
- "traefik.http.routers.coolify.rule=Host(`${DOMAIN}`) && PathPrefix(`/`)"
- "traefik.http.services.coolify.loadbalancer.server.port=3000"
- "traefik.http.routers.coolify.middlewares=global-compress"
networks:
${DOCKER_NETWORK}:
driver: overlay
name: ${DOCKER_NETWORK}
external: true

View File

@@ -1,55 +0,0 @@
require('dotenv').config()
const { program } = require('commander')
const fastify = require('fastify')()
const { schema } = require('../api/schema')
const shell = require('shelljs')
const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', '')
program.version('0.0.1')
program
.option('-d, --debug', 'Debug outputs.')
.option('-c, --check', 'Only checks configuration.')
.option('-t, --type <type>', 'Deploy type.')
program.parse(process.argv)
const options = program.opts()
if (options.check) {
checkConfig().then(() => {
console.log('Config: OK')
}).catch((err) => {
console.log('Config: NOT OK')
console.error(err)
process.exit(1)
})
} else {
if (user !== 'root') {
console.error(`Please run as root! Current user: ${user}`)
process.exit(1)
}
shell.exec(`docker network create ${process.env.DOCKER_NETWORK} --driver overlay`, { silent: !options.debug })
shell.exec('docker build -t coolify -f install/Dockerfile .')
if (options.type === 'all') {
shell.exec('docker stack rm coollabs-coolify', { silent: !options.debug })
} else if (options.type === 'coolify') {
shell.exec('docker service rm coollabs-coolify_coolify')
} else if (options.type === 'proxy') {
shell.exec('docker service rm coollabs-coolify_proxy')
}
if (options.type !== 'upgrade') {
shell.exec('set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', { silent: !options.debug, shell: '/bin/bash' })
}
}
function checkConfig () {
return new Promise((resolve, reject) => {
fastify.register(require('fastify-env'), {
schema,
dotenv: true
})
.ready((err) => {
if (err) reject(err)
resolve()
})
})
}

View File

@@ -1,4 +0,0 @@
FROM coolify-base-nodejs
WORKDIR /usr/src/app
COPY . .
RUN pnpm install

View File

@@ -1,6 +0,0 @@
FROM node:lts
LABEL coolify-preserve=true
COPY --from=coolify-binaries /usr/bin/docker /usr/bin/docker
COPY --from=coolify-binaries /usr/bin/envsubst /usr/bin/envsubst
COPY --from=coolify-binaries /usr/bin/jq /usr/bin/jq
RUN curl -f https://get.pnpm.io/v6.js | node - add --global pnpm@6

View File

@@ -1,9 +0,0 @@
FROM ubuntu:20.04
LABEL coolify-preserve=true
RUN apt update && apt install -y curl gnupg2 ca-certificates
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
RUN echo 'deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable' >> /etc/apt/sources.list
RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.2.0/envsubst-`uname -s`-`uname -m` -o /usr/bin/envsubst
RUN curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/bin/jq
RUN chmod +x /usr/bin/envsubst /usr/bin/jq
RUN apt update && apt install -y docker-ce-cli && apt clean all

View File

@@ -1,21 +0,0 @@
require('dotenv').config()
const { program } = require('commander')
const shell = require('shelljs')
const user = shell.exec('whoami', { silent: true }).stdout.replace('\n', '')
program.version('0.0.1')
program
.option('-d, --debug', 'Debug outputs.')
.option('-c, --check', 'Only checks configuration.')
.option('-t, --type <type>', 'Deploy type.')
program.parse(process.argv)
const options = program.opts()
if (user !== 'root') {
console.error(`Please run as root! Current user: ${user}`)
process.exit(1)
}
if (options.type === 'upgrade') {
shell.exec('docker service rm coollabs-coolify_coolify')
shell.exec('set -a && source .env && set +a && envsubst < install/coolify-template.yml | docker stack deploy -c - coollabs-coolify', { silent: !options.debug, shell: '/bin/bash' })
}

View File

@@ -1,66 +1,90 @@
{
"name": "coolify",
"description": "An open-source, hassle-free, self-hostable Heroku & Netlify alternative.",
"version": "1.0.6",
"license": "AGPL-3.0",
"scripts": {
"lint": "standard",
"start": "NODE_ENV=production node api/server",
"dev": "run-p dev:db dev:routify dev:svite dev:server",
"dev:db": "NODE_ENV=development node api/development/mongodb.js",
"dev:server": "nodemon -w api api/server",
"dev:routify": "routify run",
"dev:svite": "svite",
"build": "run-s build:routify build:svite",
"build:routify": "routify run -b",
"build:svite": "svite build"
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"@roxi/routify": "^2.15.1",
"@zerodevx/svelte-toast": "^0.2.1",
"axios": "^0.21.1",
"commander": "^7.2.0",
"compare-versions": "^3.6.0",
"cuid": "^2.1.8",
"dayjs": "^1.10.4",
"deepmerge": "^4.2.2",
"dockerode": "^3.2.1",
"dotenv": "^8.2.0",
"fastify": "^3.14.2",
"fastify-env": "^2.1.0",
"fastify-jwt": "^2.4.0",
"fastify-plugin": "^3.0.0",
"fastify-static": "^4.0.1",
"generate-password": "^1.6.0",
"js-yaml": "^4.0.0",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.12.3",
"shelljs": "^0.8.4",
"svelte-select": "^3.17.0",
"unique-names-generator": "^4.4.0"
},
"devDependencies": {
"mongodb-memory-server-core": "^6.9.6",
"nodemon": "^2.0.7",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.9",
"postcss-import": "^14.0.1",
"postcss-load-config": "^3.0.1",
"postcss-preset-env": "^6.7.0",
"prettier": "2.2.1",
"prettier-plugin-svelte": "^2.2.0",
"standard": "^16.0.3",
"svelte": "^3.37.0",
"svelte-hmr": "^0.14.0",
"svelte-preprocess": "^4.7.0",
"svite": "0.8.1",
"tailwindcss": "2.1.1"
},
"keywords": [
"svelte",
"routify",
"fastify",
"tailwind"
]
"name": "coolify",
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
"version": "2.4.10",
"license": "AGPL-3.0",
"scripts": {
"dev": "docker-compose -f docker-compose-dev.yaml up -d && cross-env NODE_ENV=development & svelte-kit dev",
"dev:stop": "docker-compose -f docker-compose-dev.yaml down",
"dev:logs": "docker-compose -f docker-compose-dev.yaml logs -f --tail 10",
"studio": "npx prisma studio",
"start": "npx prisma migrate deploy && npx prisma generate && npx prisma db seed && node build/index.js",
"build": "svelte-kit build",
"preview": "svelte-kit preview",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"db:generate": "prisma generate",
"db:push": "prisma db push && prisma generate",
"db:seed": "prisma db seed",
"db:migrate": "COOLIFY_DATABASE_URL=file:../db/migration.db prisma migrate dev --skip-seed --name",
"release:production:all": "cross-var docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify:$npm_package_version -t coollabsio/coolify:latest --push .",
"release:production:amd": "cross-var docker build --platform linux/amd64 -t coollabsio/coolify:$npm_package_version -t coollabsio/coolify:latest --push .",
"release:staging:all": "cross-var docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify:$npm_package_version --push .",
"release:staging:amd": "cross-var docker build --platform linux/amd64 -t coollabsio/coolify:$npm_package_version --push .",
"release:haproxy": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-alpine:latest -t coollabsio/coolify-haproxy-alpine:1.1.0 -f data/haproxy.Dockerfile --push .",
"release:haproxy:tcp": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-tcp-alpine:latest -t coollabsio/coolify-haproxy-tcp-alpine:1.1.0 -f data/haproxy-tcp.Dockerfile --push .",
"release:haproxy:http": "docker build --platform linux/amd64,linux/arm64 -t coollabsio/coolify-haproxy-http-alpine:latest -t coollabsio/coolify-haproxy-http-alpine:1.1.0 -f data/haproxy-http.Dockerfile --push .",
"prepare": "husky install"
},
"devDependencies": {
"@sveltejs/adapter-node": "1.0.0-next.73",
"@sveltejs/kit": "1.0.0-next.310",
"@types/js-cookie": "3.0.1",
"@types/js-yaml": "4.0.5",
"@types/node": "17.0.23",
"@types/node-forge": "1.0.1",
"@typescript-eslint/eslint-plugin": "4.31.1",
"@typescript-eslint/parser": "4.31.1",
"@zerodevx/svelte-toast": "0.7.1",
"autoprefixer": "10.4.4",
"cross-env": "7.0.3",
"cross-var": "1.1.0",
"eslint": "7.32.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-svelte3": "3.4.1",
"husky": "7.0.4",
"lint-staged": "12.3.7",
"postcss": "8.4.12",
"prettier": "2.6.2",
"prettier-plugin-svelte": "2.7.0",
"prettier-plugin-tailwindcss": "0.1.8",
"prisma": "3.11.1",
"svelte": "3.47.0",
"svelte-check": "2.6.0",
"svelte-preprocess": "4.10.5",
"svelte-select": "4.4.7",
"tailwindcss": "3.0.23",
"ts-node": "10.7.0",
"tslib": "2.3.1",
"typescript": "4.6.3"
},
"type": "module",
"dependencies": {
"@iarna/toml": "2.2.5",
"@prisma/client": "3.11.1",
"@sentry/node": "6.19.6",
"bcryptjs": "^2.4.3",
"bullmq": "1.80.0",
"compare-versions": "4.1.3",
"cookie": "0.4.2",
"cuid": "2.1.8",
"dayjs": "1.11.0",
"dockerode": "3.3.1",
"dotenv-extended": "2.9.0",
"generate-password": "1.7.0",
"get-port": "6.1.2",
"got": "12.0.3",
"js-cookie": "3.0.1",
"js-yaml": "4.1.0",
"jsonwebtoken": "8.5.1",
"mustache": "4.2.0",
"node-forge": "1.3.1",
"p-limit": "4.0.0",
"svelte-kit-cookie-session": "2.1.2",
"tailwindcss-scrollbar": "0.1.0",
"unique-names-generator": "4.7.1"
},
"prisma": {
"seed": "node prisma/seed.cjs"
}
}

9194
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

6
postcss.config.cjs Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

View File

@@ -1,7 +0,0 @@
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('postcss-preset-env')({ stage: 1 })
]
}

View File

@@ -0,0 +1,443 @@
-- CreateTable
CREATE TABLE "Setting" (
"id" TEXT NOT NULL PRIMARY KEY,
"fqdn" TEXT,
"isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false,
"proxyPassword" TEXT NOT NULL,
"proxyUser" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL PRIMARY KEY,
"email" TEXT NOT NULL,
"type" TEXT NOT NULL,
"password" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "Permission" (
"id" TEXT NOT NULL PRIMARY KEY,
"userId" TEXT NOT NULL,
"teamId" TEXT NOT NULL,
"permission" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Permission_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "Permission_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Team" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"databaseId" TEXT,
"serviceId" TEXT,
FOREIGN KEY ("databaseId") REFERENCES "Database" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "TeamInvitation" (
"id" TEXT NOT NULL PRIMARY KEY,
"uid" TEXT NOT NULL,
"email" TEXT NOT NULL,
"teamId" TEXT NOT NULL,
"teamName" TEXT NOT NULL,
"permission" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
CREATE TABLE "Application" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"fqdn" TEXT,
"repository" TEXT,
"configHash" TEXT,
"branch" TEXT,
"buildPack" TEXT,
"projectId" INTEGER,
"port" INTEGER,
"installCommand" TEXT,
"buildCommand" TEXT,
"startCommand" TEXT,
"baseDirectory" TEXT,
"publishDirectory" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"destinationDockerId" TEXT,
"gitSourceId" TEXT,
CONSTRAINT "Application_destinationDockerId_fkey" FOREIGN KEY ("destinationDockerId") REFERENCES "DestinationDocker" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "Application_gitSourceId_fkey" FOREIGN KEY ("gitSourceId") REFERENCES "GitSource" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "ApplicationSettings" (
"id" TEXT NOT NULL PRIMARY KEY,
"applicationId" TEXT NOT NULL,
"debug" BOOLEAN NOT NULL DEFAULT false,
"previews" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ApplicationSettings_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Secret" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"value" TEXT NOT NULL,
"isBuildSecret" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"applicationId" TEXT NOT NULL,
CONSTRAINT "Secret_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "BuildLog" (
"id" TEXT NOT NULL PRIMARY KEY,
"applicationId" TEXT,
"buildId" TEXT NOT NULL,
"line" TEXT NOT NULL,
"time" INTEGER NOT NULL
);
-- CreateTable
CREATE TABLE "Build" (
"id" TEXT NOT NULL PRIMARY KEY,
"type" TEXT NOT NULL,
"applicationId" TEXT,
"destinationDockerId" TEXT,
"gitSourceId" TEXT,
"githubAppId" TEXT,
"gitlabAppId" TEXT,
"commit" TEXT,
"status" TEXT DEFAULT 'queued',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "DestinationDocker" (
"id" TEXT NOT NULL PRIMARY KEY,
"network" TEXT NOT NULL,
"name" TEXT NOT NULL,
"engine" TEXT NOT NULL,
"remoteEngine" BOOLEAN NOT NULL DEFAULT false,
"isCoolifyProxyUsed" BOOLEAN DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "GitSource" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"type" TEXT,
"apiUrl" TEXT,
"htmlUrl" TEXT,
"organization" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"githubAppId" TEXT,
"gitlabAppId" TEXT,
CONSTRAINT "GitSource_githubAppId_fkey" FOREIGN KEY ("githubAppId") REFERENCES "GithubApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "GitSource_gitlabAppId_fkey" FOREIGN KEY ("gitlabAppId") REFERENCES "GitlabApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "GithubApp" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT,
"appId" INTEGER,
"installationId" INTEGER,
"clientId" TEXT,
"clientSecret" TEXT,
"webhookSecret" TEXT,
"privateKey" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "GitlabApp" (
"id" TEXT NOT NULL PRIMARY KEY,
"oauthId" INTEGER NOT NULL,
"groupName" TEXT,
"deployKeyId" INTEGER,
"privateSshKey" TEXT,
"publicSshKey" TEXT,
"webhookToken" TEXT,
"appId" TEXT,
"appSecret" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "Database" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"publicPort" INTEGER,
"defaultDatabase" TEXT,
"type" TEXT,
"version" TEXT,
"dbUser" TEXT,
"dbUserPassword" TEXT,
"rootUser" TEXT,
"rootUserPassword" TEXT,
"destinationDockerId" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Database_destinationDockerId_fkey" FOREIGN KEY ("destinationDockerId") REFERENCES "DestinationDocker" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "DatabaseSettings" (
"id" TEXT NOT NULL PRIMARY KEY,
"databaseId" TEXT NOT NULL,
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "DatabaseSettings_databaseId_fkey" FOREIGN KEY ("databaseId") REFERENCES "Database" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Service" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"fqdn" TEXT,
"type" TEXT,
"version" TEXT,
"destinationDockerId" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Service_destinationDockerId_fkey" FOREIGN KEY ("destinationDockerId") REFERENCES "DestinationDocker" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "PlausibleAnalytics" (
"id" TEXT NOT NULL PRIMARY KEY,
"email" TEXT,
"username" TEXT,
"password" TEXT NOT NULL,
"postgresqlUser" TEXT NOT NULL,
"postgresqlPassword" TEXT NOT NULL,
"postgresqlDatabase" TEXT NOT NULL,
"postgresqlPublicPort" INTEGER,
"secretKeyBase" TEXT,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "PlausibleAnalytics_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Minio" (
"id" TEXT NOT NULL PRIMARY KEY,
"rootUser" TEXT NOT NULL,
"rootUserPassword" TEXT NOT NULL,
"publicPort" INTEGER,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Minio_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Vscodeserver" (
"id" TEXT NOT NULL PRIMARY KEY,
"password" TEXT NOT NULL,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Vscodeserver_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Wordpress" (
"id" TEXT NOT NULL PRIMARY KEY,
"extraConfig" TEXT,
"tablePrefix" TEXT,
"mysqlUser" TEXT NOT NULL,
"mysqlPassword" TEXT NOT NULL,
"mysqlRootUser" TEXT NOT NULL,
"mysqlRootUserPassword" TEXT NOT NULL,
"mysqlDatabase" TEXT,
"mysqlPublicPort" INTEGER,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Wordpress_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_TeamToUser" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_ApplicationToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "Application" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_GitSourceToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "GitSource" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_GithubAppToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "GithubApp" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_GitlabAppToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "GitlabApp" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_DestinationDockerToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "DestinationDocker" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_DatabaseToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "Database" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "_ServiceToTeam" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,
FOREIGN KEY ("A") REFERENCES "Service" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY ("B") REFERENCES "Team" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn");
-- CreateIndex
CREATE UNIQUE INDEX "User_id_key" ON "User"("id");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Application_fqdn_key" ON "Application"("fqdn");
-- CreateIndex
CREATE UNIQUE INDEX "ApplicationSettings_applicationId_key" ON "ApplicationSettings"("applicationId");
-- CreateIndex
CREATE UNIQUE INDEX "Secret_name_key" ON "Secret"("name");
-- CreateIndex
CREATE UNIQUE INDEX "DestinationDocker_network_key" ON "DestinationDocker"("network");
-- CreateIndex
CREATE UNIQUE INDEX "GitSource_githubAppId_key" ON "GitSource"("githubAppId");
-- CreateIndex
CREATE UNIQUE INDEX "GitSource_gitlabAppId_key" ON "GitSource"("gitlabAppId");
-- CreateIndex
CREATE UNIQUE INDEX "GithubApp_name_key" ON "GithubApp"("name");
-- CreateIndex
CREATE UNIQUE INDEX "GitlabApp_oauthId_key" ON "GitlabApp"("oauthId");
-- CreateIndex
CREATE UNIQUE INDEX "GitlabApp_groupName_key" ON "GitlabApp"("groupName");
-- CreateIndex
CREATE UNIQUE INDEX "DatabaseSettings_databaseId_key" ON "DatabaseSettings"("databaseId");
-- CreateIndex
CREATE UNIQUE INDEX "PlausibleAnalytics_serviceId_key" ON "PlausibleAnalytics"("serviceId");
-- CreateIndex
CREATE UNIQUE INDEX "Minio_serviceId_key" ON "Minio"("serviceId");
-- CreateIndex
CREATE UNIQUE INDEX "Vscodeserver_serviceId_key" ON "Vscodeserver"("serviceId");
-- CreateIndex
CREATE UNIQUE INDEX "Wordpress_serviceId_key" ON "Wordpress"("serviceId");
-- CreateIndex
CREATE UNIQUE INDEX "_TeamToUser_AB_unique" ON "_TeamToUser"("A", "B");
-- CreateIndex
CREATE INDEX "_TeamToUser_B_index" ON "_TeamToUser"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_ApplicationToTeam_AB_unique" ON "_ApplicationToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_ApplicationToTeam_B_index" ON "_ApplicationToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_GitSourceToTeam_AB_unique" ON "_GitSourceToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_GitSourceToTeam_B_index" ON "_GitSourceToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_GithubAppToTeam_AB_unique" ON "_GithubAppToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_GithubAppToTeam_B_index" ON "_GithubAppToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_GitlabAppToTeam_AB_unique" ON "_GitlabAppToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_GitlabAppToTeam_B_index" ON "_GitlabAppToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_DestinationDockerToTeam_AB_unique" ON "_DestinationDockerToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_DestinationDockerToTeam_B_index" ON "_DestinationDockerToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_DatabaseToTeam_AB_unique" ON "_DatabaseToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_DatabaseToTeam_B_index" ON "_DatabaseToTeam"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_ServiceToTeam_AB_unique" ON "_ServiceToTeam"("A", "B");
-- CreateIndex
CREATE INDEX "_ServiceToTeam_B_index" ON "_ServiceToTeam"("B");

View File

@@ -0,0 +1,28 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Team" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"databaseId" TEXT,
"serviceId" TEXT
);
INSERT INTO "new_Team" ("createdAt", "databaseId", "id", "name", "serviceId", "updatedAt") SELECT "createdAt", "databaseId", "id", "name", "serviceId", "updatedAt" FROM "Team";
DROP TABLE "Team";
ALTER TABLE "new_Team" RENAME TO "Team";
CREATE TABLE "new_DatabaseSettings" (
"id" TEXT NOT NULL PRIMARY KEY,
"databaseId" TEXT NOT NULL,
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"appendOnly" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "DatabaseSettings_databaseId_fkey" FOREIGN KEY ("databaseId") REFERENCES "Database" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
INSERT INTO "new_DatabaseSettings" ("createdAt", "databaseId", "id", "isPublic", "updatedAt") SELECT "createdAt", "databaseId", "id", "isPublic", "updatedAt" FROM "DatabaseSettings";
DROP TABLE "DatabaseSettings";
ALTER TABLE "new_DatabaseSettings" RENAME TO "DatabaseSettings";
CREATE UNIQUE INDEX "DatabaseSettings_databaseId_key" ON "DatabaseSettings"("databaseId");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,11 @@
/*
Warnings:
- A unique constraint covering the columns `[name,applicationId]` on the table `Secret` will be added. If there are existing duplicate values, this will fail.
*/
-- DropIndex
DROP INDEX "Secret_name_key";
-- CreateIndex
CREATE UNIQUE INDEX "Secret_name_applicationId_key" ON "Secret"("name", "applicationId");

View File

@@ -0,0 +1,47 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Setting" (
"id" TEXT NOT NULL PRIMARY KEY,
"fqdn" TEXT,
"isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"proxyPassword" TEXT NOT NULL,
"proxyUser" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
INSERT INTO "new_Setting" ("createdAt", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt") SELECT "createdAt", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting";
DROP TABLE "Setting";
ALTER TABLE "new_Setting" RENAME TO "Setting";
CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn");
CREATE TABLE "new_ApplicationSettings" (
"id" TEXT NOT NULL PRIMARY KEY,
"applicationId" TEXT NOT NULL,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"debug" BOOLEAN NOT NULL DEFAULT false,
"previews" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ApplicationSettings_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
INSERT INTO "new_ApplicationSettings" ("applicationId", "createdAt", "debug", "id", "previews", "updatedAt") SELECT "applicationId", "createdAt", "debug", "id", "previews", "updatedAt" FROM "ApplicationSettings";
DROP TABLE "ApplicationSettings";
ALTER TABLE "new_ApplicationSettings" RENAME TO "ApplicationSettings";
CREATE UNIQUE INDEX "ApplicationSettings_applicationId_key" ON "ApplicationSettings"("applicationId");
CREATE TABLE "new_Service" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"fqdn" TEXT,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"type" TEXT,
"version" TEXT,
"destinationDockerId" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Service_destinationDockerId_fkey" FOREIGN KEY ("destinationDockerId") REFERENCES "DestinationDocker" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_Service" ("createdAt", "destinationDockerId", "fqdn", "id", "name", "type", "updatedAt", "version") SELECT "createdAt", "destinationDockerId", "fqdn", "id", "name", "type", "updatedAt", "version" FROM "Service";
DROP TABLE "Service";
ALTER TABLE "new_Service" RENAME TO "Service";
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,19 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Secret" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"value" TEXT NOT NULL,
"isPRMRSecret" BOOLEAN NOT NULL DEFAULT false,
"isBuildSecret" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"applicationId" TEXT NOT NULL,
CONSTRAINT "Secret_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
INSERT INTO "new_Secret" ("applicationId", "createdAt", "id", "isBuildSecret", "name", "updatedAt", "value") SELECT "applicationId", "createdAt", "id", "isBuildSecret", "name", "updatedAt", "value" FROM "Secret";
DROP TABLE "Secret";
ALTER TABLE "new_Secret" RENAME TO "Secret";
CREATE UNIQUE INDEX "Secret_name_applicationId_isPRMRSecret_key" ON "Secret"("name", "applicationId", "isPRMRSecret");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,20 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Setting" (
"id" TEXT NOT NULL PRIMARY KEY,
"fqdn" TEXT,
"isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"minPort" INTEGER NOT NULL DEFAULT 9000,
"maxPort" INTEGER NOT NULL DEFAULT 9100,
"proxyPassword" TEXT NOT NULL,
"proxyUser" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
INSERT INTO "new_Setting" ("createdAt", "dualCerts", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt") SELECT "createdAt", "dualCerts", "fqdn", "id", "isRegistrationEnabled", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting";
DROP TABLE "Setting";
ALTER TABLE "new_Setting" RENAME TO "Setting";
CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Setting" ADD COLUMN "proxyHash" TEXT;

View File

@@ -0,0 +1,13 @@
-- CreateTable
CREATE TABLE "ServiceSecret" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"value" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"serviceId" TEXT NOT NULL,
CONSTRAINT "ServiceSecret_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "ServiceSecret_name_serviceId_key" ON "ServiceSecret"("name", "serviceId");

View File

@@ -0,0 +1,19 @@
-- RedefineTables
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_ApplicationSettings" (
"id" TEXT NOT NULL PRIMARY KEY,
"applicationId" TEXT NOT NULL,
"dualCerts" BOOLEAN NOT NULL DEFAULT false,
"debug" BOOLEAN NOT NULL DEFAULT false,
"previews" BOOLEAN NOT NULL DEFAULT false,
"autodeploy" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ApplicationSettings_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
INSERT INTO "new_ApplicationSettings" ("applicationId", "createdAt", "debug", "dualCerts", "id", "previews", "updatedAt") SELECT "applicationId", "createdAt", "debug", "dualCerts", "id", "previews", "updatedAt" FROM "ApplicationSettings";
DROP TABLE "ApplicationSettings";
ALTER TABLE "new_ApplicationSettings" RENAME TO "ApplicationSettings";
CREATE UNIQUE INDEX "ApplicationSettings_applicationId_key" ON "ApplicationSettings"("applicationId");
PRAGMA foreign_key_check;
PRAGMA foreign_keys=ON;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Application" ADD COLUMN "phpModules" TEXT;

View File

@@ -0,0 +1,18 @@
-- CreateTable
CREATE TABLE "ApplicationPersistentStorage" (
"id" TEXT NOT NULL PRIMARY KEY,
"applicationId" TEXT NOT NULL,
"path" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "ApplicationPersistentStorage_applicationId_fkey" FOREIGN KEY ("applicationId") REFERENCES "Application" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "ApplicationPersistentStorage_applicationId_key" ON "ApplicationPersistentStorage"("applicationId");
-- CreateIndex
CREATE UNIQUE INDEX "ApplicationPersistentStorage_path_key" ON "ApplicationPersistentStorage"("path");
-- CreateIndex
CREATE UNIQUE INDEX "ApplicationPersistentStorage_applicationId_path_key" ON "ApplicationPersistentStorage"("applicationId", "path");

View File

@@ -0,0 +1,19 @@
-- CreateTable
CREATE TABLE "Ghost" (
"id" TEXT NOT NULL PRIMARY KEY,
"defaultEmail" TEXT NOT NULL,
"defaultPassword" TEXT NOT NULL,
"mariadbUser" TEXT NOT NULL,
"mariadbPassword" TEXT NOT NULL,
"mariadbRootUser" TEXT NOT NULL,
"mariadbRootUserPassword" TEXT NOT NULL,
"mariadbDatabase" TEXT,
"mariadbPublicPort" INTEGER,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "Ghost_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "Ghost_serviceId_key" ON "Ghost"("serviceId");

View File

@@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "Application" ADD COLUMN "pythonModule" TEXT;
ALTER TABLE "Application" ADD COLUMN "pythonVariable" TEXT;
ALTER TABLE "Application" ADD COLUMN "pythonWSGI" TEXT;

View File

@@ -0,0 +1,12 @@
-- CreateTable
CREATE TABLE "MeiliSearch" (
"id" TEXT NOT NULL PRIMARY KEY,
"masterKey" TEXT NOT NULL,
"serviceId" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "MeiliSearch_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "MeiliSearch_serviceId_key" ON "MeiliSearch"("serviceId");

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