diff --git a/docs/docker.md b/docs/docker.md new file mode 100644 index 00000000..9b035a62 --- /dev/null +++ b/docs/docker.md @@ -0,0 +1,90 @@ +## Docker + +There is a supplied docker image to make deploying a server as a container easier. + +```sh +docker run -d -v "$USER/.config/atuin:/config" ghcr.io/ellie/atuin:latest server start +``` + +## Docker Compose + +Using the already build docker image hosting your own Atuin can be done using the supplied docker-compose file. + +Create a `.env` file next to `docker-compose.yml` with contents like this: + +``` +ATUIN_DB_USERNAME=atuin +# Choose your own secure password +ATUIN_DB_PASSWORD=really-insecure +``` + +Create a `docker-compose.yml`: + +```yaml +version: '3.5' +services: + atuin: + restart: always + image: ghcr.io/ellie/atuin:main + command: server start + volumes: + - "./config:/config" + links: + - postgresql:db + ports: + - 8888:8888 + environment: + ATUIN_HOST: "0.0.0.0" + ATUIN_OPEN_REGISTRATION: "true" + ATUIN_DB_URI: postgres://$ATUIN_DB_USERNAME:$ATUIN_DB_PASSWORD@db/atuin + postgresql: + image: postgres:14 + restart: unless-stopped + volumes: # Don't remove permanent storage for index database files! + - "./database:/var/lib/postgresql/data/" + environment: + POSTGRES_USER: $ATUIN_DB_USERNAME + POSTGRES_PASSWORD: $ATUIN_DB_PASSWORD + POSTGRES_DB: atuin +``` + +Start the services using `docker-compose`: + +```sh +docker-compose up -d +``` + +### Using systemd to manage your atuin server + +The following `systemd` unit file to manage your `docker-compose` managed service: + +``` +[Unit] +Description=Docker Compose Atuin Service +Requires=docker.service +After=docker.service + +[Service] +# Where the docker-compose file is located +WorkingDirectory=/srv/atuin-server +ExecStart=/usr/bin/docker-compose up +ExecStop=/usr/bin/docker-compose down +TimeoutStartSec=0 +Restart=on-failure +StartLimitBurst=3 + +[Install] +WantedBy=multi-user.target +``` + +Start and enable the service with: + +```sh +systemctl enable --now atuin +``` + +Check if its running with: + +```sh +systemctl status atuin +``` diff --git a/docs/k8s.md b/docs/k8s.md new file mode 100644 index 00000000..c4a4d615 --- /dev/null +++ b/docs/k8s.md @@ -0,0 +1,196 @@ +## Kubernetes + +You could host your own Atuin server using the Kubernetes platform. + +Create a [`secrets.yaml`](../k8s/secrets.yaml) file for the database credentials: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: atuin-secrets +type: Opaque +stringData: + ATUIN_DB_USERNAME: atuin + ATUIN_DB_PASSWORD: seriously-insecure + ATUIN_HOST: "127.0.0.1" + ATUIN_PORT: "8888" + ATUIN_OPEN_REGISTRATION: "true" + ATUIN_DB_URI: "postgres://atuin:seriously-insecure@localhost/atuin" +immutable: true +``` + +Create a [`atuin.yaml`](../k8s/atuin.yaml) file for the Atuin server: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: atuin +spec: + replicas: 1 + selector: + matchLabels: + io.kompose.service: atuin + template: + metadata: + labels: + io.kompose.service: atuin + spec: + containers: + - args: + - server + - start + env: + - name: ATUIN_DB_URI + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_URI + optional: false + - name: ATUIN_HOST + value: 0.0.0.0 + - name: ATUIN_PORT + value: "8888" + - name: ATUIN_OPEN_REGISTRATION + value: "true" + image: ghcr.io/ellie/atuin:main + name: atuin + ports: + - containerPort: 8888 + resources: + limits: + cpu: 250m + memory: 1Gi + requests: + cpu: 250m + memory: 1Gi + volumeMounts: + - mountPath: /config + name: atuin-claim0 + - name: postgresql + image: postgres:14 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + value: atuin + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_PASSWORD + optional: false + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_USERNAME + optional: false + resources: + limits: + cpu: 250m + memory: 1Gi + requests: + cpu: 250m + memory: 1Gi + volumeMounts: + - mountPath: /var/lib/postgresql/data/ + name: database + volumes: + - name: database + persistentVolumeClaim: + claimName: database + - name: atuin-claim0 + persistentVolumeClaim: + claimName: atuin-claim0 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + io.kompose.service: atuin + name: atuin +spec: + type: NodePort + ports: + - name: "8888" + port: 8888 + nodePort: 30530 + selector: + io.kompose.service: atuin +--- +kind: PersistentVolume +apiVersion: v1 +metadata: + name: database-pv + labels: + app: database + type: local +spec: + storageClassName: manual + capacity: + storage: 300Mi + accessModes: + - ReadWriteOnce + hostPath: + path: "/Users/firstname.lastname/.kube/database" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: database + name: database +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 300Mi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: atuin-claim0 + name: atuin-claim0 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi +``` + +Finally, you may want to use a separate namespace for atuin, by creating a [`namespace.yaml`](../k8s/namespaces.yaml) file: + +```yaml + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: atuin-namespace + labels: + name: atuin +``` + +Note that this configuration will store the database folder _outside_ the kubernetes cluster, in the folder `/Users/firstname.lastname/.kube/database` of the host system by configuring the `storageClassName` to be `manual`. In a real enterprise setup, you would probably want to store the database content permanently in the cluster, and not in the host system. + +You should also change the password string in `ATUIN_DB_PASSWORD` and `ATUIN_DB_URI` in the`secrets.yaml` file to a more secure one. + +The atuin service on the port `30530` of the host system. That is configured by the `nodePort` property. Kubernetes has a strict rule that you are not allowed to expose a port numbered lower than 30000. To make the clients work, you can simply set the port in in your `config.toml` file, e.g. `sync_address = "http://192.168.1.10:30530"`. + +Deploy the Atuin server using `kubectl`: + +```shell + kubectl apply -f ./namespaces.yaml + kubectl apply -n atuin-namespace \ + -f ./secrets.yaml \ + -f ./atuin.yaml +``` + +The sample files above are also in the [k8s](../k8s) folder of the atuin repository. diff --git a/docs/server.md b/docs/server.md index a50f187b..79e62239 100644 --- a/docs/server.md +++ b/docs/server.md @@ -67,94 +67,9 @@ Defaults to `false`. A valid postgres URI, where the user and history data will be saved to. -## Docker +## Container deployment instructions -There is a supplied docker image to make deploying a server as a container easier. - -```sh -docker run -d -v "$USER/.config/atuin:/config" ghcr.io/ellie/atuin:latest server start -``` - -## Docker Compose - -Using the already build docker image hosting your own Atuin can be done using the supplied docker-compose file. - -Create a `.env` file next to `docker-compose.yml` with contents like this: - -``` -ATUIN_DB_USERNAME=atuin -# Choose your own secure password -ATUIN_DB_PASSWORD=really-insecure -``` - -Create a `docker-compose.yml`: - -```yaml -version: '3.5' -services: - atuin: - restart: always - image: ghcr.io/ellie/atuin:main - command: server start - volumes: - - "./config:/config" - links: - - postgresql:db - ports: - - 8888:8888 - environment: - ATUIN_HOST: "0.0.0.0" - ATUIN_OPEN_REGISTRATION: "true" - ATUIN_DB_URI: postgres://$ATUIN_DB_USERNAME:$ATUIN_DB_PASSWORD@db/atuin - postgresql: - image: postgres:14 - restart: unless-stopped - volumes: # Don't remove permanent storage for index database files! - - "./database:/var/lib/postgresql/data/" - environment: - POSTGRES_USER: $ATUIN_DB_USERNAME - POSTGRES_PASSWORD: $ATUIN_DB_PASSWORD - POSTGRES_DB: atuin -``` - -Start the services using `docker-compose`: - -```sh -docker-compose up -d -``` - -### Using systemd to manage your atuin server - -The following `systemd` unit file to manage your `docker-compose` managed service: - -``` -[Unit] -Description=Docker Compose Atuin Service -Requires=docker.service -After=docker.service - -[Service] -# Where the docker-compose file is located -WorkingDirectory=/srv/atuin-server -ExecStart=/usr/bin/docker-compose up -ExecStop=/usr/bin/docker-compose down -TimeoutStartSec=0 -Restart=on-failure -StartLimitBurst=3 - -[Install] -WantedBy=multi-user.target -``` - -Start and enable the service with: - -```sh -systemctl enable --now atuin -``` - -Check if its running with: - -```sh -systemctl status atuin -``` +You can deploy you own atuin server in a container: +* See [docker](docker.md) for a sample docker configuration. +* See [k8s](k8s.md) for a sample kubernetes configuration. diff --git a/k8s/atuin.yaml b/k8s/atuin.yaml new file mode 100644 index 00000000..b4df0b21 --- /dev/null +++ b/k8s/atuin.yaml @@ -0,0 +1,140 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: atuin +spec: + replicas: 1 + selector: + matchLabels: + io.kompose.service: atuin + template: + metadata: + labels: + io.kompose.service: atuin + spec: + containers: + - args: + - server + - start + env: + - name: ATUIN_DB_URI + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_URI + optional: false + - name: ATUIN_HOST + value: 0.0.0.0 + - name: ATUIN_PORT + value: "8888" + - name: ATUIN_OPEN_REGISTRATION + value: "true" + image: ghcr.io/ellie/atuin:main + name: atuin + ports: + - containerPort: 8888 + resources: + limits: + cpu: 250m + memory: 1Gi + requests: + cpu: 250m + memory: 1Gi + volumeMounts: + - mountPath: /config + name: atuin-claim0 + - name: postgresql + image: postgres:14 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_DB + value: atuin + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_PASSWORD + optional: false + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: atuin-secrets + key: ATUIN_DB_USERNAME + optional: false + resources: + limits: + cpu: 250m + memory: 1Gi + requests: + cpu: 250m + memory: 1Gi + volumeMounts: + - mountPath: /var/lib/postgresql/data/ + name: database + volumes: + - name: database + persistentVolumeClaim: + claimName: database + - name: atuin-claim0 + persistentVolumeClaim: + claimName: atuin-claim0 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + io.kompose.service: atuin + name: atuin +spec: + type: NodePort + ports: + - name: "8888" + port: 8888 + nodePort: 31929 + selector: + io.kompose.service: atuin +--- +kind: PersistentVolume +apiVersion: v1 +metadata: + name: database-pv + labels: + app: database + type: local +spec: + storageClassName: manual + capacity: + storage: 300Mi + accessModes: + - ReadWriteOnce + hostPath: + path: "/Users/firstname.lastname/.kube/database" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: database + name: database +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 300Mi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + io.kompose.service: atuin-claim0 + name: atuin-claim0 +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi diff --git a/k8s/namespaces.yaml b/k8s/namespaces.yaml new file mode 100644 index 00000000..20a401f6 --- /dev/null +++ b/k8s/namespaces.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: atuin-namespace + labels: + name: atuin diff --git a/k8s/secrets.yaml b/k8s/secrets.yaml new file mode 100644 index 00000000..d6391fad --- /dev/null +++ b/k8s/secrets.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: atuin-secrets +type: Opaque +stringData: + ATUIN_DB_USERNAME: atuin + ATUIN_DB_PASSWORD: seriously-insecure + ATUIN_HOST: "127.0.0.1" + ATUIN_PORT: "8888" + ATUIN_OPEN_REGISTRATION: "true" + ATUIN_DB_URI: "postgres://atuin:seriously-insecure@localhost/atuin" +immutable: true