diff --git a/crates/rustainers/src/lib.rs b/crates/rustainers/src/lib.rs
new file mode 100644
index 0000000..f5d224f
--- /dev/null
+++ b/crates/rustainers/src/lib.rs
@@ -0,0 +1,244 @@
+extern crate tar;
+
+use bollard::container::{Config, CreateContainerOptions, StartContainerOptions};
+use bollard::exec::{CreateExecOptions, StartExecResults};
+use bollard::Docker;
+use bytes::{BufMut, BytesMut};
+use futures_util::stream::StreamExt;
+use futures_util::TryStreamExt;
+use passwd::PasswdEntry;
+use rand::Rng;
+use std::collections::HashMap;
+use std::io::Read;
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum DockerContainerGuardError {
+    #[error("Docker API error: {0}")]
+    DockerError(#[from] bollard::errors::Error),
+
+    #[error("File not found: {0}")]
+    FileNotFound(String),
+
+    #[error("Failed to extract file: {0}")]
+    FileExtractionFailed(#[from] std::io::Error),
+
+    #[error("Too many files in tarball")]
+    TooManyFilesInTarball,
+
+    #[error("Failed to parse password entry: {0}")]
+    FailedToParsePasswdEntry(#[from] passwd::PasswdEntryError),
+
+    #[error("User not found: {0}")]
+    UserNotFound(String),
+}
+
+#[derive(Debug)]
+pub struct DockerContainerGuard {
+    pub id: String,
+    pub image: String,
+    docker: Docker,
+}
+
+impl DockerContainerGuard {
+    // Spawns a new container using Bollard.
+    //
+    // The container is automatically cleaned up when the guard goes out of scope.
+    pub async fn spawn(image_name: &str) -> Result<Self, DockerContainerGuardError> {
+        let docker = Docker::connect_with_local_defaults()?;
+
+        let container_name: String = rand::thread_rng()
+            .sample_iter(&rand::distributions::Alphanumeric)
+            .take(10)
+            .map(char::from)
+            .collect();
+
+        docker
+            .create_image(
+                Some(bollard::image::CreateImageOptions {
+                    from_image: image_name,
+                    ..Default::default()
+                }),
+                None,
+                None,
+            )
+            .try_collect::<Vec<_>>()
+            .await?;
+
+        let container = docker
+            .create_container(
+                Some(CreateContainerOptions {
+                    name: container_name,
+                    ..Default::default()
+                }),
+                Config {
+                    image: Some(image_name),
+                    cmd: Some(vec!["sh"]),
+                    tty: Some(true),
+                    ..Default::default()
+                },
+            )
+            .await?;
+
+        docker
+            .start_container(&container.id, None::<StartContainerOptions<String>>)
+            .await?;
+
+        Ok(Self {
+            id: container.id,
+            image: image_name.to_string(),
+            docker,
+        })
+    }
+
+    /// Executes a command inside the container using Bollard.
+    ///
+    /// Returns the output as a String.
+    pub async fn exec(&self, cmd: Vec<&str>) -> Result<String, bollard::errors::Error> {
+        let exec_instance = self
+            .docker
+            .create_exec(
+                &self.id,
+                CreateExecOptions {
+                    attach_stdout: Some(true),
+                    attach_stderr: Some(true),
+                    cmd: Some(cmd.iter().map(|s| s.to_string()).collect()),
+                    ..Default::default()
+                },
+            )
+            .await?;
+        let start_exec_result = self.docker.start_exec(&exec_instance.id, None).await?;
+
+        if let StartExecResults::Attached {
+            output: out_stream, ..
+        } = start_exec_result
+        {
+            let output = out_stream
+                .filter_map(|chunk| async {
+                    match chunk {
+                        Ok(bollard::container::LogOutput::StdOut { message })
+                        | Ok(bollard::container::LogOutput::StdErr { message }) => {
+                            Some(String::from_utf8_lossy(&message).to_string())
+                        }
+                        _ => None,
+                    }
+                })
+                .fold(String::new(), |mut acc, item| async move {
+                    acc.push_str(&item);
+                    acc
+                })
+                .await;
+
+            return Ok(output);
+        }
+
+        Ok(String::new())
+    }
+
+    // Read a file from the container.
+    pub async fn read_file(&self, path: &str) -> Result<String, DockerContainerGuardError> {
+        let bytes = self
+            .docker
+            .download_from_container::<String>(
+                &self.id,
+                Some(bollard::container::DownloadFromContainerOptions { path: path.into() }),
+            )
+            .try_fold(BytesMut::new(), |mut bytes, b| async move {
+                bytes.put(b);
+                Ok(bytes)
+            })
+            .await?;
+
+        if bytes.len() == 0 {
+            return Err(DockerContainerGuardError::FileNotFound(path.into()));
+        }
+
+        for file in tar::Archive::new(&bytes[..]).entries()? {
+            let mut s = String::new();
+            file?.read_to_string(&mut s).unwrap();
+            return Ok(s);
+        }
+
+        Err(DockerContainerGuardError::FileNotFound(path.into()))
+    }
+
+    // Get a HashMap of all users in the container.
+    pub async fn get_users(
+        &self,
+    ) -> Result<HashMap<String, PasswdEntry>, DockerContainerGuardError> {
+        let output = self.read_file("/etc/passwd").await?;
+
+        return output
+            .lines()
+            .map(|line| {
+                PasswdEntry::from_line(line)
+                    .map(|entry| (entry.name.clone(), entry))
+                    .map_err(DockerContainerGuardError::from)
+            })
+            .collect();
+    }
+
+    // Get a specific user from the container.
+    pub async fn get_user(&self, name: &str) -> Result<PasswdEntry, DockerContainerGuardError> {
+        let users = self.get_users().await?;
+        let user = users
+            .get(name)
+            .ok_or_else(|| DockerContainerGuardError::UserNotFound(name.into()))?;
+
+        Ok(user.clone())
+    }
+}
+
+impl Drop for DockerContainerGuard {
+    fn drop(&mut self) {
+        let docker = self.docker.clone();
+        let container_id = self.id.clone();
+
+        tokio::spawn(async move {
+            docker
+                .remove_container(
+                    &container_id,
+                    Some(bollard::container::RemoveContainerOptions {
+                        force: true,
+                        ..Default::default()
+                    }),
+                )
+                .await
+        });
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[tokio::test]
+    async fn test_container_exec() -> Result<(), DockerContainerGuardError> {
+        let guard = DockerContainerGuard::spawn("alpine:latest").await?;
+
+        let output = guard.exec(vec!["echo", "hello from container"]).await?;
+        assert!(output.contains("hello from container"));
+
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_container_read_file() -> Result<(), DockerContainerGuardError> {
+        let guard = DockerContainerGuard::spawn("alpine:latest").await?;
+
+        let file = guard.read_file("/usr/lib/os-release").await?;
+        assert!(file.len() > 0);
+
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_container_get_user() -> Result<(), DockerContainerGuardError> {
+        let guard = DockerContainerGuard::spawn("alpine:latest").await?;
+
+        let user = guard.get_user("root").await?;
+        assert_eq!(user.name, "root");
+
+        Ok(())
+    }
+}
