commit
						5ff6c53715
					
				| @ -93,15 +93,13 @@ Deploy your resource to: | |||||||
| - [Fider](https://fider.io) | - [Fider](https://fider.io) | ||||||
| - [Hasura](https://hasura.io) | - [Hasura](https://hasura.io) | ||||||
| - [GlitchTip](https://glitchtip.com) | - [GlitchTip](https://glitchtip.com) | ||||||
| 
 | - And more... | ||||||
| ## Migration from v1 |  | ||||||
| 
 |  | ||||||
| A fresh installation is necessary. v2 and v3 are not compatible with v1. |  | ||||||
| 
 | 
 | ||||||
| ## Support | ## Support | ||||||
| 
 | 
 | ||||||
| - Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai) | - Mastodon: [@andrasbacsai@fosstodon.org](https://fosstodon.org/@andrasbacsai) | ||||||
| - Telegram: [@andrasbacsai](https://t.me/andrasbacsai) | - Telegram: [@andrasbacsai](https://t.me/andrasbacsai) | ||||||
|  | - Twitter: [@andrasbacsai](https://twitter.com/andrasbacsai) | ||||||
| - Email: [andras@coollabs.io](mailto:andras@coollabs.io) | - Email: [andras@coollabs.io](mailto:andras@coollabs.io) | ||||||
| - Discord: [Invitation](https://coollabs.io/discord) | - Discord: [Invitation](https://coollabs.io/discord) | ||||||
| 
 | 
 | ||||||
|  | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,3 +1,65 @@ | |||||||
|  | - templateVersion: 1.0.0 | ||||||
|  |   defaultVersion: v3.6 | ||||||
|  |   documentation: https://github.com/freyacodes/Lavalink | ||||||
|  |   description: Standalone audio sending node based on Lavaplayer. | ||||||
|  |   type: lavalink | ||||||
|  |   name: Lavalink | ||||||
|  |   labels: | ||||||
|  |     - discord | ||||||
|  |     - discord bot | ||||||
|  |     - audio | ||||||
|  |     - lavalink | ||||||
|  |     - jda | ||||||
|  |   services: | ||||||
|  |     $$id: | ||||||
|  |       name: Lavalink | ||||||
|  |       image: fredboat/lavalink:$$core_version | ||||||
|  |       environment: [] | ||||||
|  |       volumes: | ||||||
|  |         - $$id-lavalink:/lavalink | ||||||
|  |       ports: | ||||||
|  |         - "2333" | ||||||
|  |       files: | ||||||
|  |         - location: /opt/Lavalink/application.yml | ||||||
|  |           content: >- | ||||||
|  |             server: | ||||||
|  |               port: $$config_port | ||||||
|  |               address: 0.0.0.0 | ||||||
|  |             lavalink: | ||||||
|  |               server: | ||||||
|  |                 password: "$$secret_password" | ||||||
|  |                 sources: | ||||||
|  |                   youtube: true | ||||||
|  |                   bandcamp: true | ||||||
|  |                   soundcloud: true | ||||||
|  |                   twitch: true | ||||||
|  |                   vimeo: true | ||||||
|  |                   http: true | ||||||
|  |                   local: false | ||||||
|  | 
 | ||||||
|  |             logging: | ||||||
|  |               file: | ||||||
|  |                 path: ./logs/ | ||||||
|  | 
 | ||||||
|  |               level: | ||||||
|  |                 root: INFO | ||||||
|  |                 lavalink: INFO | ||||||
|  | 
 | ||||||
|  |               logback: | ||||||
|  |                 rollingpolicy: | ||||||
|  |                   max-file-size: 1GB | ||||||
|  |                   max-history: 30 | ||||||
|  |   variables: | ||||||
|  |     - id: $$config_port | ||||||
|  |       name: PORT | ||||||
|  |       label: Port | ||||||
|  |       defaultValue: '2333' | ||||||
|  |       required: true | ||||||
|  |     - id: $$secret_password | ||||||
|  |       name: PASSWORD | ||||||
|  |       label: Password | ||||||
|  |       defaultValue: $$generate_password | ||||||
|  |       required: true | ||||||
| - templateVersion: 1.0.0 | - templateVersion: 1.0.0 | ||||||
|   defaultVersion: v1.8.6 |   defaultVersion: v1.8.6 | ||||||
|   documentation: https://docs.appsmith.com/getting-started/setup/instance-configuration/ |   documentation: https://docs.appsmith.com/getting-started/setup/instance-configuration/ | ||||||
| @ -2385,7 +2447,7 @@ | |||||||
|       name: MySQL |       name: MySQL | ||||||
|       depends_on: [] |       depends_on: [] | ||||||
|       image: "bitnami/mysql:5.7" |       image: "bitnami/mysql:5.7" | ||||||
|       imageArm: "mysql:5.7" |       imageArm: "mysql:8.0" | ||||||
|       volumes: |       volumes: | ||||||
|         - "$$id-mysql-data:/bitnami/mysql/data" |         - "$$id-mysql-data:/bitnami/mysql/data" | ||||||
|       volumesArm: |       volumesArm: | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import { day } from './dayjs'; | |||||||
| import { saveBuildLog } from './buildPacks/common'; | import { saveBuildLog } from './buildPacks/common'; | ||||||
| import { scheduler } from './scheduler'; | import { scheduler } from './scheduler'; | ||||||
| 
 | 
 | ||||||
| export const version = '3.11.4'; | export const version = '3.11.5'; | ||||||
| export const isDev = process.env.NODE_ENV === 'development'; | export const isDev = process.env.NODE_ENV === 'development'; | ||||||
| 
 | 
 | ||||||
| const algorithm = 'aes-256-ctr'; | const algorithm = 'aes-256-ctr'; | ||||||
| @ -972,7 +972,7 @@ export function generateDatabaseConfiguration(database: any, arch: string): Data | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| export function isARM(arch: string) { | export function isARM(arch: string) { | ||||||
| 	if (arch === 'arm' || arch === 'arm64') { | 	if (arch === 'arm' || arch === 'arm64' || arch === 'aarch' || arch === 'aarch64') { | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 	return false; | 	return false; | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ export async function startService(request: FastifyRequest<ServiceStartStop>, fa | |||||||
|         const { id } = request.params; |         const { id } = request.params; | ||||||
|         const teamId = request.user.teamId; |         const teamId = request.user.teamId; | ||||||
|         const service = await getServiceFromDB({ id, teamId }); |         const service = await getServiceFromDB({ id, teamId }); | ||||||
|         const arm = isARM(service.arch) |         const arm = isARM(process.arch); | ||||||
|         const { type, destinationDockerId, destinationDocker, persistentStorage, exposePort } = |         const { type, destinationDockerId, destinationDocker, persistentStorage, exposePort } = | ||||||
|             service; |             service; | ||||||
| 
 | 
 | ||||||
| @ -103,15 +103,22 @@ export async function startService(request: FastifyRequest<ServiceStartStop>, fa | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |             let port = null | ||||||
|  |             if (template.services[s].ports?.length > 0) { | ||||||
|  |                 port = template.services[s].ports[0] | ||||||
|  |             } | ||||||
|  |             let image = template.services[s].image | ||||||
|  |             if (arm && template.services[s].imageArm) { | ||||||
|  |                 image = template.services[s].imageArm | ||||||
|  |             } | ||||||
|             config[s] = { |             config[s] = { | ||||||
|                 container_name: s, |                 container_name: s, | ||||||
|                 build: template.services[s].build || undefined, |                 build: template.services[s].build || undefined, | ||||||
|                 command: template.services[s].command, |                 command: template.services[s].command, | ||||||
|                 entrypoint: template.services[s]?.entrypoint, |                 entrypoint: template.services[s]?.entrypoint, | ||||||
|                 image: arm ? template.services[s].imageArm : template.services[s].image, |                 image, | ||||||
|                 expose: template.services[s].ports, |                 expose: template.services[s].ports, | ||||||
|                 ...(exposePort ? { ports: [`${exposePort}:${exposePort}`] } : {}), |                 ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), | ||||||
|                 volumes: Array.from(volumes), |                 volumes: Array.from(volumes), | ||||||
|                 environment: newEnvironments, |                 environment: newEnvironments, | ||||||
|                 depends_on: template.services[s]?.depends_on, |                 depends_on: template.services[s]?.depends_on, | ||||||
| @ -121,6 +128,7 @@ export async function startService(request: FastifyRequest<ServiceStartStop>, fa | |||||||
|                 labels: makeLabelForServices(type), |                 labels: makeLabelForServices(type), | ||||||
|                 ...defaultComposeConfiguration(network), |                 ...defaultComposeConfiguration(network), | ||||||
|             } |             } | ||||||
|  |             console.log(config[s].image) | ||||||
| 
 | 
 | ||||||
|             // Generate files for builds
 |             // Generate files for builds
 | ||||||
|             if (template.services[s]?.files?.length > 0) { |             if (template.services[s]?.files?.length > 0) { | ||||||
|  | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -16,9 +16,11 @@ | |||||||
| 		updateStatus.loading = true; | 		updateStatus.loading = true; | ||||||
| 		try { | 		try { | ||||||
| 			if (dev) { | 			if (dev) { | ||||||
| 				await asyncSleep(4000); | 				localStorage.setItem('lastVersion', $appSession.version); | ||||||
|  | 				await asyncSleep(1000); | ||||||
| 				return window.location.reload(); | 				return window.location.reload(); | ||||||
| 			} else { | 			} else { | ||||||
|  | 				localStorage.setItem('lastVersion', $appSession.version); | ||||||
| 				await post(`/update`, { type: 'update', latestVersion }); | 				await post(`/update`, { type: 'update', latestVersion }); | ||||||
| 				addToast({ | 				addToast({ | ||||||
| 					message: 'Update completed.<br><br>Waiting for the new version to start...', | 					message: 'Update completed.<br><br>Waiting for the new version to start...', | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| 	export let type: string; | 	export let type: string; | ||||||
| 	export let isAbsolute = false; | 	export let isAbsolute = false; | ||||||
| 
 |  | ||||||
| 	let extension = 'png'; | 	let extension = 'png'; | ||||||
| 	let svgs = [ | 	let svgs = [ | ||||||
| 		'languagetool', | 		'languagetool', | ||||||
| @ -31,8 +30,14 @@ | |||||||
| 	function generateClass() { | 	function generateClass() { | ||||||
| 		switch (name) { | 		switch (name) { | ||||||
| 			case 'n8n': | 			case 'n8n': | ||||||
|  | 				if (isAbsolute) { | ||||||
|  | 					return 'w-12 h-12 absolute -m-9 -mt-12'; | ||||||
|  | 				} | ||||||
| 				return 'w-12 h-12 -mt-3'; | 				return 'w-12 h-12 -mt-3'; | ||||||
| 			case 'weblate': | 			case 'weblate': | ||||||
|  | 				if (isAbsolute) { | ||||||
|  | 					return 'w-12 h-12 absolute -m-9 -mt-12'; | ||||||
|  | 				} | ||||||
| 				return 'w-12 h-12 -mt-3'; | 				return 'w-12 h-12 -mt-3'; | ||||||
| 			default: | 			default: | ||||||
| 				return isAbsolute ? 'w-10 h-10 absolute -m-4 -mt-9 left-0' : 'w-10 h-10'; | 				return isAbsolute ? 'w-10 h-10 absolute -m-4 -mt-9 left-0' : 'w-10 h-10'; | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ | |||||||
| 	import { addToast, appSession, features } from '$lib/store'; | 	import { addToast, appSession, features } from '$lib/store'; | ||||||
| 	import { asyncSleep, errorNotification, getDomain } from '$lib/common'; | 	import { asyncSleep, errorNotification, getDomain } from '$lib/common'; | ||||||
| 	import Explainer from '$lib/components/Explainer.svelte'; | 	import Explainer from '$lib/components/Explainer.svelte'; | ||||||
|  | 	import { dev } from '$app/env'; | ||||||
| 
 | 
 | ||||||
| 	let isAPIDebuggingEnabled = settings.isAPIDebuggingEnabled; | 	let isAPIDebuggingEnabled = settings.isAPIDebuggingEnabled; | ||||||
| 	let isRegistrationEnabled = settings.isRegistrationEnabled; | 	let isRegistrationEnabled = settings.isRegistrationEnabled; | ||||||
| @ -45,9 +46,61 @@ | |||||||
| 		save: false, | 		save: false, | ||||||
| 		remove: false, | 		remove: false, | ||||||
| 		proxyMigration: false, | 		proxyMigration: false, | ||||||
| 		restart: false | 		restart: false, | ||||||
|  | 		rollback: false | ||||||
| 	}; | 	}; | ||||||
|  | 	let rollbackVersion = localStorage.getItem('lastVersion'); | ||||||
| 
 | 
 | ||||||
|  | 	async function rollback() { | ||||||
|  | 		if (rollbackVersion) { | ||||||
|  | 			const sure = confirm(`Are you sure you want rollback Coolify to ${rollbackVersion}?`); | ||||||
|  | 			if (sure) { | ||||||
|  | 				try { | ||||||
|  | 					loading.rollback = true; | ||||||
|  | 					console.log('loading.rollback', loading.rollback); | ||||||
|  | 					if (dev) { | ||||||
|  | 						console.log('rolling back to', rollbackVersion); | ||||||
|  | 						await asyncSleep(4000); | ||||||
|  | 						return window.location.reload(); | ||||||
|  | 					} else { | ||||||
|  | 						addToast({ | ||||||
|  | 							message: 'Rollback started...', | ||||||
|  | 							type: 'success' | ||||||
|  | 						}); | ||||||
|  | 						await post(`/update`, { type: 'update', latestVersion: rollbackVersion }); | ||||||
|  | 						addToast({ | ||||||
|  | 							message: 'Rollback completed.<br><br>Waiting for the new version to start...', | ||||||
|  | 							type: 'success' | ||||||
|  | 						}); | ||||||
|  | 
 | ||||||
|  | 						let reachable = false; | ||||||
|  | 						let tries = 0; | ||||||
|  | 						do { | ||||||
|  | 							await asyncSleep(4000); | ||||||
|  | 							try { | ||||||
|  | 								await get(`/undead`); | ||||||
|  | 								reachable = true; | ||||||
|  | 							} catch (error) { | ||||||
|  | 								reachable = false; | ||||||
|  | 							} | ||||||
|  | 							if (reachable) break; | ||||||
|  | 							tries++; | ||||||
|  | 						} while (!reachable || tries < 120); | ||||||
|  | 						addToast({ | ||||||
|  | 							message: 'New version reachable. Reloading...', | ||||||
|  | 							type: 'success' | ||||||
|  | 						}); | ||||||
|  | 						await asyncSleep(3000); | ||||||
|  | 						return window.location.reload(); | ||||||
|  | 					} | ||||||
|  | 				} catch (error) { | ||||||
|  | 					return errorNotification(error); | ||||||
|  | 				} finally { | ||||||
|  | 					loading.rollback = false; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	async function removeFqdn() { | 	async function removeFqdn() { | ||||||
| 		if (fqdn) { | 		if (fqdn) { | ||||||
| 			loading.remove = true; | 			loading.remove = true; | ||||||
| @ -281,6 +334,17 @@ | |||||||
| 						</div> | 						</div> | ||||||
| 					{/if} | 					{/if} | ||||||
| 				</div> | 				</div> | ||||||
|  | 				<div class="grid grid-cols-2 items-center"> | ||||||
|  | 					<Setting | ||||||
|  | 						id="dualCerts" | ||||||
|  | 						dataTooltip={$t('setting.must_remove_domain_before_changing')} | ||||||
|  | 						disabled={isFqdnSet} | ||||||
|  | 						bind:setting={dualCerts} | ||||||
|  | 						title={$t('application.ssl_www_and_non_www')} | ||||||
|  | 						description={$t('setting.generate_www_non_www_ssl')} | ||||||
|  | 						on:click={() => !isFqdnSet && changeSettings('dualCerts')} | ||||||
|  | 					/> | ||||||
|  | 				</div> | ||||||
| 				<div class="grid grid-cols-2 items-center"> | 				<div class="grid grid-cols-2 items-center"> | ||||||
| 					<div> | 					<div> | ||||||
| 						Default Redirect URL | 						Default Redirect URL | ||||||
| @ -300,16 +364,29 @@ | |||||||
| 						placeholder="{$t('forms.eg')}: https://coolify.io" | 						placeholder="{$t('forms.eg')}: https://coolify.io" | ||||||
| 					/> | 					/> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div class="grid grid-cols-2 items-center"> | 
 | ||||||
| 					<Setting | 				<div class="grid grid-cols-4 items-center"> | ||||||
| 						id="dualCerts" | 					<div class="col-span-2"> | ||||||
| 						dataTooltip={$t('setting.must_remove_domain_before_changing')} | 						Rollback to a specific version | ||||||
| 						disabled={isFqdnSet} | 						<Explainer | ||||||
| 						bind:setting={dualCerts} | 							position="dropdown-bottom" | ||||||
| 						title={$t('application.ssl_www_and_non_www')} | 							explanation="You can rollback to a specific version of Coolify. This will not affect your current running resources.<br><br><a href='https://github.com/coollabsio/coolify/releases' target='_blank'>See available versions</a>" | ||||||
| 						description={$t('setting.generate_www_non_www_ssl')} | 						/> | ||||||
| 						on:click={() => !isFqdnSet && changeSettings('dualCerts')} | 					</div> | ||||||
|  | 					<input | ||||||
|  | 						class="w-full" | ||||||
|  | 						bind:value={rollbackVersion} | ||||||
|  | 						readonly={!$appSession.isAdmin} | ||||||
|  | 						disabled={!$appSession.isAdmin} | ||||||
|  | 						name="rollbackVersion" | ||||||
|  | 						id="rollbackVersion" | ||||||
| 					/> | 					/> | ||||||
|  | 					<button | ||||||
|  | 						class:loading={loading.rollback} | ||||||
|  | 						class="btn btn-primary ml-2" | ||||||
|  | 						disabled={!rollbackVersion || loading.rollback} | ||||||
|  | 						on:click|preventDefault|stopPropagation={rollback}>Rollback</button | ||||||
|  | 					> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div class="grid grid-cols-2 items-center"> | 				<div class="grid grid-cols-2 items-center"> | ||||||
| 					<div> | 					<div> | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								apps/ui/static/icons/lavalink.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								apps/ui/static/icons/lavalink.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 28 KiB | 
| @ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "name": "coolify", |   "name": "coolify", | ||||||
|   "description": "An open-source & self-hostable Heroku / Netlify alternative.", |   "description": "An open-source & self-hostable Heroku / Netlify alternative.", | ||||||
|   "version": "3.11.4", |   "version": "3.11.5", | ||||||
|   "license": "Apache-2.0", |   "license": "Apache-2.0", | ||||||
|   "repository": "github:coollabsio/coolify", |   "repository": "github:coollabsio/coolify", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user