@@ -16,7 +16,7 @@ interface ServerConfig {
16
16
domain: string
17
17
region: string
18
18
type: string
19
- size: keyof typeof workerSizes
19
+ size: InstanceType
20
20
diskSize: number
21
21
privateNetwork? : string
22
22
subnet? : string
@@ -40,6 +40,14 @@ interface WorkerConfig {
40
40
specs: WorkerSizeSpecs
41
41
}
42
42
43
+ // Add type for server type
44
+ interface ServerType {
45
+ value: string
46
+ label: string
47
+ badges: string []
48
+ description: string
49
+ }
50
+
43
51
// Available options for dropdowns
44
52
const regions = [
45
53
' us-east-1' ,
@@ -52,43 +60,104 @@ const regions = [
52
60
' ap-southeast-2' ,
53
61
]
54
62
55
- const instanceTypes = [
56
- ' t3.nano' ,
63
+ type InstanceType = keyof typeof workerSizes
64
+
65
+ // Update instance types to match Forge's offerings
66
+ const instanceTypes: InstanceType [] = [
67
+ ' t2.micro' ,
68
+ ' t2.small' ,
69
+ ' t2.medium' ,
70
+ ' t2.large' ,
71
+ ' t2.xlarge' ,
72
+ ' t2.2xlarge' ,
57
73
' t3.micro' ,
58
74
' t3.small' ,
59
75
' t3.medium' ,
60
76
' t3.large' ,
61
77
' t3.xlarge' ,
62
78
' t3.2xlarge' ,
63
- ' c6a.large' ,
64
- ' c6a.xlarge' ,
65
- ' c6a.2xlarge' ,
66
- ' c6a.4xlarge' ,
67
- ' m6a.large' ,
68
- ' m6a.xlarge' ,
69
- ' m6a.2xlarge' ,
70
- ' m6a.4xlarge' ,
71
- ' r6a.large' ,
72
- ' r6a.xlarge' ,
73
- ' r6a.2xlarge' ,
74
- ' r6a.4xlarge' ,
75
- ]
76
-
77
- const serverTypes = [
78
- { value: ' app' , label: ' Application Server' },
79
- { value: ' web' , label: ' Web Server' },
80
- { value: ' worker' , label: ' Worker Server' },
81
- { value: ' cache' , label: ' Cache Server' },
82
- { value: ' search' , label: ' Search Server' },
79
+ ' m5.large' ,
80
+ ' m5.xlarge' ,
81
+ ' m5.4xlarge' ,
82
+ ' m5.2xlarge' ,
83
+ ' m5d.large' ,
84
+ ' m5d.xlarge' ,
85
+ ' c5.large' ,
86
+ ' c5.xlarge' ,
87
+ ' c5.2xlarge' ,
88
+ ' c5.4xlarge' ,
89
+ ' c5.9xlarge' ,
90
+ ' t4g.micro' ,
91
+ ' t4g.small' ,
92
+ ' t4g.medium' ,
93
+ ' t4g.large' ,
94
+ ' t4g.xlarge' ,
95
+ ' t4g.2xlarge' ,
83
96
]
84
97
85
98
const operatingSystems = [
86
- ' ubuntu-20 -lts-x86_64' ,
99
+ ' ubuntu-24 -lts-x86_64' ,
87
100
' ubuntu-22-lts-x86_64' ,
101
+ ' ubuntu-20-lts-x86_64' ,
88
102
' debian-11-x86_64' ,
89
103
' amazon-linux-2-x86_64' ,
90
104
]
91
105
106
+ const serverTypes: ServerType [] = [
107
+ {
108
+ value: ' app' ,
109
+ label: ' Application Server' ,
110
+ badges: [' Bun' , ' Nginx' , ' Redis' , ' Memcached' , ' Search Engine' ],
111
+ description: ' These servers are meant to be networked to dedicated cache or database servers.'
112
+ },
113
+ {
114
+ value: ' web' ,
115
+ label: ' Web Server' ,
116
+ badges: [' Bun' , ' Nginx' ],
117
+ description: ' A secured web server with Nginx and PHP.'
118
+ },
119
+ {
120
+ value: ' worker' ,
121
+ label: ' Dedicated Worker Server' ,
122
+ badges: [' Bun' ],
123
+ description: ' Connect to your local database / cache server to keep your queued jobs processing quickly.'
124
+ },
125
+ {
126
+ value: ' cache' ,
127
+ label: ' Cache Server' ,
128
+ badges: [' Redis' , ' Memcached' ],
129
+ description: ' Dedicated cache server for improved performance.'
130
+ },
131
+ {
132
+ value: ' database' ,
133
+ label: ' Database Server' ,
134
+ badges: [' Database' ],
135
+ description: ' Separate your app from your data with a dedicated database. Choose from MySQL, PostgreSQL, or MariaDB.'
136
+ },
137
+ {
138
+ value: ' search' ,
139
+ label: ' Search Server' ,
140
+ badges: [' Search Engine' , ' Nginx' ],
141
+ description: ' Search your data with Meilisearch.'
142
+ },
143
+ {
144
+ value: ' loadbalancer' ,
145
+ label: ' Load Balancer' ,
146
+ badges: [' Nginx' ],
147
+ description: ' Share server load with a load balancer. Distribute traffic between two or more servers.'
148
+ }
149
+ ]
150
+
151
+ const bunVersions = [
152
+ ' v1.0.30' ,
153
+ ' v1.0.25' ,
154
+ ' v1.0.20' ,
155
+ ' v1.0.15' ,
156
+ ' v1.0.10' ,
157
+ ' v1.0.5' ,
158
+ ' v1.0.0' ,
159
+ ]
160
+
92
161
// State
93
162
const activeView = ref <' visual' | ' code' >(' visual' )
94
163
const cloudConfig = ref <CloudConfig >({
@@ -130,27 +199,37 @@ interface InfraLink {
130
199
target: string | InfraNode
131
200
}
132
201
133
- // Update worker sizes with type safety
202
+ // Update worker sizes with accurate specs
134
203
const workerSizes = {
135
- ' t3.nano' : { vcpu: 2 , ram: 512 },
204
+ ' t2.micro' : { vcpu: 1 , ram: 1024 },
205
+ ' t2.small' : { vcpu: 1 , ram: 2048 },
206
+ ' t2.medium' : { vcpu: 2 , ram: 4096 },
207
+ ' t2.large' : { vcpu: 2 , ram: 8192 },
208
+ ' t2.xlarge' : { vcpu: 4 , ram: 16384 },
209
+ ' t2.2xlarge' : { vcpu: 8 , ram: 32768 },
136
210
' t3.micro' : { vcpu: 2 , ram: 1024 },
137
211
' t3.small' : { vcpu: 2 , ram: 2048 },
138
212
' t3.medium' : { vcpu: 2 , ram: 4096 },
139
213
' t3.large' : { vcpu: 2 , ram: 8192 },
140
214
' t3.xlarge' : { vcpu: 4 , ram: 16384 },
141
215
' t3.2xlarge' : { vcpu: 8 , ram: 32768 },
142
- ' c6a.large' : { vcpu: 2 , ram: 4096 },
143
- ' c6a.xlarge' : { vcpu: 4 , ram: 8192 },
144
- ' c6a.2xlarge' : { vcpu: 8 , ram: 16384 },
145
- ' c6a.4xlarge' : { vcpu: 16 , ram: 32768 },
146
- ' m6a.large' : { vcpu: 2 , ram: 8192 },
147
- ' m6a.xlarge' : { vcpu: 4 , ram: 16384 },
148
- ' m6a.2xlarge' : { vcpu: 8 , ram: 32768 },
149
- ' m6a.4xlarge' : { vcpu: 16 , ram: 65536 },
150
- ' r6a.large' : { vcpu: 2 , ram: 16384 },
151
- ' r6a.xlarge' : { vcpu: 4 , ram: 32768 },
152
- ' r6a.2xlarge' : { vcpu: 8 , ram: 65536 },
153
- ' r6a.4xlarge' : { vcpu: 16 , ram: 131072 },
216
+ ' m5.large' : { vcpu: 2 , ram: 8192 },
217
+ ' m5.xlarge' : { vcpu: 4 , ram: 16384 },
218
+ ' m5.4xlarge' : { vcpu: 16 , ram: 65536 },
219
+ ' m5.2xlarge' : { vcpu: 8 , ram: 32768 },
220
+ ' m5d.large' : { vcpu: 2 , ram: 8192 },
221
+ ' m5d.xlarge' : { vcpu: 4 , ram: 16384 },
222
+ ' c5.large' : { vcpu: 2 , ram: 4096 },
223
+ ' c5.xlarge' : { vcpu: 4 , ram: 8192 },
224
+ ' c5.2xlarge' : { vcpu: 8 , ram: 16384 },
225
+ ' c5.4xlarge' : { vcpu: 16 , ram: 32768 },
226
+ ' c5.9xlarge' : { vcpu: 36 , ram: 73728 },
227
+ ' t4g.micro' : { vcpu: 2 , ram: 1024 },
228
+ ' t4g.small' : { vcpu: 2 , ram: 2048 },
229
+ ' t4g.medium' : { vcpu: 2 , ram: 4096 },
230
+ ' t4g.large' : { vcpu: 2 , ram: 8192 },
231
+ ' t4g.xlarge' : { vcpu: 4 , ram: 16384 },
232
+ ' t4g.2xlarge' : { vcpu: 8 , ram: 32768 },
154
233
} as const
155
234
156
235
type WorkerSize = keyof typeof workerSizes
@@ -927,28 +1006,94 @@ const saveWorkerConfig = async () => {
927
1006
928
1007
<div >
929
1008
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Type</label >
1009
+ <div class =" relative" >
1010
+ <select
1011
+ v-model =" server.type"
1012
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 pl-3 pr-10 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1013
+ >
1014
+ <option v-for =" type in serverTypes" :key =" type.value" :value =" type.value" >
1015
+ {{ type.label }}
1016
+ </option >
1017
+ </select >
1018
+ </div >
1019
+ <div v-if =" server.type" class =" mt-2" >
1020
+ <div class =" flex flex-wrap gap-2" >
1021
+ <span
1022
+ v-for =" badge in serverTypes.find((t: ServerType) => t.value === server.type)?.badges"
1023
+ :key =" badge"
1024
+ class =" inline-flex items-center px-2 py-1 rounded-md text-xs font-medium"
1025
+ :class =" {
1026
+ 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300': badge === 'Bun',
1027
+ 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300': badge === 'Nginx',
1028
+ 'bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-300': badge === 'Database',
1029
+ 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300': badge === 'Redis' || badge === 'Memcached',
1030
+ 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-300': badge === 'Search Engine'
1031
+ }"
1032
+ >
1033
+ {{ badge }}
1034
+ </span >
1035
+ </div >
1036
+ <p class =" mt-1 text-sm text-gray-500 dark:text-gray-400" >
1037
+ {{ serverTypes.find((t: ServerType) => t.value === server.type)?.description }}
1038
+ </p >
1039
+ </div >
1040
+ </div >
1041
+
1042
+ <div >
1043
+ <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Bun Version</label >
930
1044
<select
931
- v-model =" server.type "
1045
+ v-model =" server.bunVersion "
932
1046
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
933
1047
>
934
- <option v-for =" type in serverTypes " :key =" type.value " :value =" type.value " >
935
- {{ type.label }}
1048
+ <option v-for =" version in bunVersions " :key =" version " :value =" version " >
1049
+ {{ version }}
936
1050
</option >
937
1051
</select >
938
1052
</div >
939
1053
940
1054
<div >
941
- <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Size </label >
1055
+ <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Database </label >
942
1056
<select
943
- v-model =" server.size "
1057
+ v-model =" server.database "
944
1058
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
945
1059
>
946
- <option v-for =" size in instanceTypes" :key =" size" :value =" size" >
947
- {{ size }} ({{ workerSizes[size].vcpu }} vCPU, {{ (workerSizes[size].ram / 1024).toFixed(1) }}GB RAM)
948
- </option >
1060
+ <option value =" " >None</option >
1061
+ <option value =" mysql" >MySQL</option >
1062
+ <option value =" postgresql" >PostgreSQL</option >
1063
+ <option value =" sqlite" >SQLite</option >
1064
+ <option value =" mongodb" >MongoDB</option >
949
1065
</select >
950
1066
</div >
951
1067
1068
+ <div v-if =" server.database" >
1069
+ <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Database Name</label >
1070
+ <input
1071
+ v-model =" server.databaseName"
1072
+ type =" text"
1073
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1074
+ placeholder =" my_database"
1075
+ >
1076
+ </div >
1077
+
1078
+ <div >
1079
+ <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Size</label >
1080
+ <div class =" relative" >
1081
+ <select
1082
+ v-model =" server.size"
1083
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1084
+ >
1085
+ <option v-for =" size in instanceTypes" :key =" size" :value =" size" >
1086
+ {{ (workerSizes[size as keyof typeof workerSizes].ram / 1024).toFixed(0) }}GB RAM ({{ size }}) (64-bit {{ size.includes('g.') ? 'arm' : 'x86' }}) - {{ workerSizes[size as keyof typeof workerSizes].vcpu }} vCPUs
1087
+ </option >
1088
+ </select >
1089
+ <div class =" absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none" >
1090
+ <svg xmlns =" http://www.w3.org/2000/svg" fill =" none" viewBox =" 0 0 24 24" stroke-width =" 1.5" stroke =" currentColor" class =" w-5 h-5 text-gray-400" >
1091
+ <path stroke-linecap =" round" stroke-linejoin =" round" d =" M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" />
1092
+ </svg >
1093
+ </div >
1094
+ </div >
1095
+ </div >
1096
+
952
1097
<div >
953
1098
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Operating System</label >
954
1099
<select
0 commit comments