Skip to content

Commit

Permalink
feat!: move appdata directory deeper
Browse files Browse the repository at this point in the history
  • Loading branch information
hugojosefson committed May 7, 2024
1 parent 2ab69d0 commit 0dc8c25
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 21 deletions.
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ that did a similar thing for Proxmox VE.
- [x] You have an `apps` directory on the TrueNAS SCALE server.
- [x] Each container/app:
- [x] Has a subdirectory in `apps`, with the app's name.
- [x] It contains the app's `docker-compose.yml` file.
- [x] It is bind mounted inside the container as `/appdata`.
- [x] It has a subdirectory `appdata` inside it, for the app's data.
- [x] It contains the app's `docker-compose.yml` file.
- [x] It is bind mounted inside the container as `/appdata`.
- [x] Has `docker-compose` installed, and runs the app via its
`docker-compose.yml`.
`/appdata/docker-compose.yml`.
- [x] Watches the `docker-compose.yml` file for changes, and restarts the app
when it changes.
- [x] Is exposed on the network with a static IP, or DHCP.
- [x] CLI script(s) to easily create a new container/app.
- [x] Sets up a new subdirectory in `apps`.
- [x] Puts an example `docker-compose.yml` into the new subdirectory.
- [x] Puts an example `docker-compose.yml` into the new subdirectory's
`appdata` directory.
- [x] Creates a new container with:
- [x] a static IP, or DHCP;
- [x] the new subdirectory as the bind mount;
Expand All @@ -38,7 +40,7 @@ that did a similar thing for Proxmox VE.

- [ ] Put each app's configuration (ip(s), extra bind-mounts, image, etc) in a
`<appName>/incus-app-container.yml` file in the app's subdirectory.
- [ ] The app container has a subdirectory `<appName>/appdata/` mounted as
- [x] The app container has a subdirectory `<appName>/appdata/` mounted as
`/appdata` inside the container, so it can't reach its own configuration.
- [ ] No scripts to run, just an always running container that watches the
`apps/` directory for changes, and:
Expand All @@ -50,9 +52,10 @@ that did a similar thing for Proxmox VE.
- [ ] stops (doesn't start) containers if they have file `<appName>/disabled`.
- [ ] The service keeps track of its own containers by setting a label on them,
and only manages containers with that label.
- [x] Each `docker-compose.yml` is by default prepared with a service that keeps
its docker images up to date. It's a third-party tool, called
[Watchtower](https://containrrr.dev/watchtower/).
- [x] ~~Each `docker-compose.yml` is by default prepared with a service that
keeps its docker images up to date. It's a third-party tool, called
[Watchtower](https://containrrr.dev/watchtower/).~~
- [x] Updates the images automatically, using Podman's built-in image updater.
- [x] Inside each incus app container, there's a service that watches the
`docker-compose.yml` file for changes, and reloads the app when it
changes.
Expand Down Expand Up @@ -93,7 +96,6 @@ watch -n0.2 'ps -ef | grep -v "ps -ef"'
```sh
# run the watchdog manually
service docker-compose-watchdog stop
killall inotifyd
docker-compose-watchdog
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const IDMAP_BASE_SIZE = 100_000;
* - check owner/group of existing app dirs (immediate subdirs of apps)
* - minimum: {@link IDMAP_BASE_MIN}
* - based on the highest uid or gid that owns an immediate subdirectory of apps, choose the next even million that is at least {@link IDMAP_BASE_SIZE} larger than the existing.
* @param appsDir the directory where appdata directories are stored
* @param appsDir the directory where app directories are stored
*/
export async function getNextIdmapBaseFor(
appsDir: AbsolutePath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import { toTemplateName } from "../../supported-image.ts";
import { type Vlan } from "../../vlan.ts";
import { CreateAppContainerOptions } from "./options.ts";

export type AppdataDir<Name extends string> = `${string | ""}/apps/${Name}`;
export type AppDir<Name extends string> = `${string | ""}/apps/${Name}`;
export type AppDataDir<Name extends string> = `${
| string
| ""}/apps/${Name}/appdata`;
export type AppContainer<Name extends string> = {
name: Name;
appdataDir: AppdataDir<Name>;
appDir: AppDir<Name>;
};

async function getNics(): Promise<string[][]> {
Expand Down Expand Up @@ -44,6 +47,8 @@ export async function createAppContainer<
name: Name,
options: CreateAppContainerOptions<AppsDir>,
): Promise<AppContainer<Name>> {
const appDir = `${options.appsDir}/${name}` as AppDir<Name>;
const appDataDir = `${appDir}/appdata` as AppDataDir<Name>;
{
using spinner = new StatusSpinnerResource(name, {
pending: "Creating container...",
Expand Down Expand Up @@ -169,16 +174,15 @@ iface ${nicParentName} inet manual
`size=${options.diskSize}`,
]);

const appdataDir = `${options.appsDir}/${name}` as AppdataDir<Name>;
await Deno.mkdir(appdataDir, { recursive: true });
await Deno.mkdir(appDir, { recursive: true });
await run([
"chown",
"-R",
`${options.idmapBase}:${options.idmapBase}`,
appdataDir,
appDir,
]); // because Deno.chown is not recursive
spinner.currentStatus =
`creating bind-mount from host:${appdataDir} to ${name}:/appdata`;
`creating bind-mount from host:${appDataDir} to ${name}:/appdata`;
await run([
"incus",
"config",
Expand All @@ -187,7 +191,7 @@ iface ${nicParentName} inet manual
name,
"appdata-bind-mount",
"disk",
`source=${appdataDir}`,
`source=${appDataDir}`,
`path=/appdata`,
]);
}
Expand Down Expand Up @@ -266,6 +270,6 @@ iface ${nicParentName} inet manual

return {
name,
appdataDir: `${options.appsDir}/${name}` as AppdataDir<Name>,
appDir,
};
}
6 changes: 3 additions & 3 deletions src/incus-app-container-files/cli/create-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export async function createCli<
{
default: defaults?.create?.appsDir ?? defaults.appsDir ?? "/mnt/apps",
description:
"Base directory for where all app containers' appdata are (to be) stored.",
"Base directory for where all app containers' metadata and appdata are (to be) stored.",
cast: await enforceType(
isAbsolutePath,
"an absolute path, for example /mnt/apps",
Expand All @@ -123,7 +123,7 @@ export async function createCli<
.action(
async (name: string, inputOptions) => {
const options = await resolveCreateAppContainerOptions(inputOptions);
const { appdataDir } = await createAppContainer(name, options);
const { appDir } = await createAppContainer(name, options);
if (options.start) {
await run(["incus", "start", name]);
await untilStatusCode(
Expand All @@ -135,7 +135,7 @@ export async function createCli<
},
);
}
console.log(appdataDir);
console.log(appDir);
},
);

Expand Down

0 comments on commit 0dc8c25

Please sign in to comment.