Skip to content

Commit d17060a

Browse files
committed
WIP deploy
1 parent ef080cf commit d17060a

File tree

1 file changed

+105
-9
lines changed

1 file changed

+105
-9
lines changed

.dagger/src/index.ts

Lines changed: 105 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export class AtomicServer {
188188
}
189189

190190
@func()
191-
rustBuild(): Container {
191+
rustBuild(@argument() release: boolean = false): Container {
192192
const source = this.source;
193193
const cargoCache = dag.cacheVolume("cargo");
194194

@@ -220,14 +220,25 @@ export class AtomicServer {
220220
browserDir
221221
);
222222

223+
const buildArgs = release
224+
? ["cargo", "build", "--release"]
225+
: ["cargo", "build"];
226+
const binaryPath = release
227+
? "./target/release/atomic-server"
228+
: "./target/debug/atomic-server";
229+
const targetPath = release
230+
? "/code/target/release/atomic-server"
231+
: "/code/target/debug/atomic-server";
232+
223233
return containerWithAssets
224-
.withExec(["cargo", "build"])
225-
.withExec(["./target/release/atomic-server", "--version"])
226-
.withExec([
227-
"cp",
228-
"/code/target/release/atomic-server",
229-
"/atomic-server-binary",
230-
]);
234+
.withExec(buildArgs)
235+
.withExec([binaryPath, "--version"])
236+
.withExec(["cp", targetPath, "/atomic-server-binary"]);
237+
}
238+
239+
@func()
240+
rustReleaseBuild(): Container {
241+
return this.rustBuild(true);
231242
}
232243

233244
@func()
@@ -265,7 +276,8 @@ export class AtomicServer {
265276
.from(RUST_IMAGE)
266277
.withExec(["cargo", "install", "cross"])
267278
.withMountedDirectory("/code", source)
268-
.withWorkdir("/code");
279+
.withWorkdir("/code")
280+
.withExec(["rustup", "target", "add", target]);
269281

270282
return rustContainer
271283
.withExec(["cross", "build", "--target", target, "--release"])
@@ -355,4 +367,88 @@ export class AtomicServer {
355367

356368
return deployUrl;
357369
}
370+
371+
@func()
372+
async deployServer(
373+
@argument() remoteHost: string,
374+
@argument() remoteUser: Secret,
375+
@argument() sshPrivateKey: Secret
376+
): Promise<string> {
377+
// Build the cross-compiled binary for x86_64-unknown-linux-musl
378+
const crossBuildContainer = this.rustCrossBuild(
379+
"x86_64-unknown-linux-musl"
380+
);
381+
const binaryFile = crossBuildContainer.file(
382+
"/code/target/x86_64-unknown-linux-musl/release/atomic-server"
383+
);
384+
385+
// Create deployment container with SSH client
386+
const deployContainer = dag
387+
.container()
388+
.from("alpine:latest")
389+
.withExec(["apk", "add", "--no-cache", "openssh-client", "rsync"])
390+
.withFile("/atomic-server-binary", binaryFile, { permissions: 0o755 });
391+
392+
// Setup SSH key
393+
const sshContainer = deployContainer
394+
.withExec(["mkdir", "-p", "/root/.ssh"])
395+
.withSecretVariable("SSH_PRIVATE_KEY", sshPrivateKey)
396+
.withExec(["sh", "-c", 'echo "$SSH_PRIVATE_KEY" > /root/.ssh/id_rsa'])
397+
.withExec(["chmod", "600", "/root/.ssh/id_rsa"])
398+
.withExec(["ssh-keyscan", "-H", remoteHost])
399+
.withExec([
400+
"sh",
401+
"-c",
402+
`ssh-keyscan -H ${remoteHost} >> /root/.ssh/known_hosts`,
403+
]);
404+
405+
// Transfer binary using rsync
406+
const transferResult = await sshContainer
407+
.withSecretVariable("REMOTE_USER", remoteUser)
408+
.withExec([
409+
"sh",
410+
"-c",
411+
`rsync -rltgoDzvO /atomic-server-binary $REMOTE_USER@${remoteHost}:~/atomic-server-x86_64-unknown-linux-musl`,
412+
])
413+
.stdout();
414+
415+
// Execute deployment commands on remote server
416+
const deployResult = await sshContainer
417+
.withSecretVariable("REMOTE_USER", remoteUser)
418+
.withExec([
419+
"sh",
420+
"-c",
421+
`ssh -i /root/.ssh/id_rsa $REMOTE_USER@${remoteHost} '
422+
mv ~/atomic-server-x86_64-unknown-linux-musl ~/atomic-server &&
423+
cp ~/atomic-server ~/atomic-server-$(date +"%Y-%m-%dT%H:%M:%S") &&
424+
systemctl stop atomic &&
425+
./atomic-server export &&
426+
systemctl start atomic &&
427+
systemctl status atomic
428+
'`,
429+
])
430+
.stdout();
431+
432+
return `Deployment to ${remoteHost} completed successfully:\n${deployResult}`;
433+
}
434+
435+
@func()
436+
async deployStaging(
437+
@argument() remoteUser: Secret,
438+
@argument() sshPrivateKey: Secret
439+
): Promise<string> {
440+
return this.deployServer(
441+
"staging.atomicdata.dev",
442+
remoteUser,
443+
sshPrivateKey
444+
);
445+
}
446+
447+
@func()
448+
async deployProduction(
449+
@argument() remoteUser: Secret,
450+
@argument() sshPrivateKey: Secret
451+
): Promise<string> {
452+
return this.deployServer("atomicdata.dev", remoteUser, sshPrivateKey);
453+
}
358454
}

0 commit comments

Comments
 (0)