Shipyard is a minimal Blazor Server app for monitoring and managing Docker or Podman containers.
- View containers
- See image, state, status, ports, and creation time
- Start stopped containers
- Stop running containers
- View recent stdout and stderr logs
- Optional dashboard auto-refresh
- Configure Docker or Podman from a persistent config file
- .NET 8
- Blazor Server
- Docker.DotNet
- Docker socket access through
/var/run/docker.sock - Podman API socket support
- Docker image and Compose support
- Dev container for local development
After the container image workflow has published the image, run Shipyard without cloning the repository:
docker pull ghcr.io/darthza/shipyard:latest
docker run --rm \
--name shipyard \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v shipyard-config:/config \
ghcr.io/darthza/shipyard:latestBuild and run Shipyard:
docker compose up --buildOpen:
http://localhost:8080
Build the image:
docker build -t shipyard:local .Run Shipyard with access to the host Docker socket:
docker run --rm \
--name shipyard \
-p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v shipyard-config:/config \
shipyard:localMore Docker options are documented in docs/docker.md.
Enable the Podman API socket:
systemctl --user enable --now podman.socketRun Shipyard with access to the rootless Podman socket:
podman run --rm \
--name shipyard \
-p 8080:8080 \
-v "$XDG_RUNTIME_DIR/podman/podman.sock:/var/run/podman/podman.sock" \
-v shipyard-config:/config \
--security-opt label=disable \
ghcr.io/darthza/shipyard:latestMore Podman options are documented in docs/podman.md.
The recommended workflow is to open this repository in the dev container. The dev container mounts the host Docker socket so Shipyard can inspect and control local Docker containers. You can also configure Shipyard to use a Podman socket.
Run the app:
dotnet run --project src/Shipyard.Web/Shipyard.Web.csproj --urls http://0.0.0.0:8080Open:
http://localhost:8080
Shipyard reads optional configuration from:
/config/shipyard.json
Example Docker configuration:
{
"ContainerEngine": {
"Type": "docker",
"Endpoint": "unix:///var/run/docker.sock"
}
}Example Podman configuration:
{
"ContainerEngine": {
"Type": "podman",
"Endpoint": "unix:///var/run/podman/podman.sock"
}
}Mount /config to a Docker or Podman volume so this file survives container recreation.
Restore packages:
dotnet restore Shipyard.slnBuild:
dotnet build Shipyard.slnClean build:
dotnet clean Shipyard.sln
dotnet build Shipyard.slnBuild the dev container image manually:
docker build -f .devcontainer/Dockerfile -t shipyard-dev .devcontainerBuild inside the dev container image:
docker run --rm \
-v "$PWD:/workspaces/shipyard" \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /workspaces/shipyard \
shipyard-dev \
dotnet build Shipyard.slnShipyard uses the Docker socket to manage containers. Mounting /var/run/docker.sock gives the app broad control over the host Docker daemon. Use this setup only in trusted local development environments.
Pointing Shipyard at a Docker or Podman API gives it control over that container engine. Only configure trusted endpoints.
.
├── .devcontainer/
│ ├── devcontainer.json
│ └── Dockerfile
├── .github/
│ └── workflows/
│ └── container-image.yml
├── docs/
│ ├── architecture.md
│ ├── docker.md
│ └── podman.md
├── src/
│ └── Shipyard.Web/
│ ├── Components/
│ ├── Models/
│ ├── Services/
│ └── Program.cs
├── LICENSE
├── README.md
├── config/
│ ├── shipyard.example.json
│ └── shipyard.podman.example.json
├── compose.podman.yaml
├── compose.yaml
├── Dockerfile
└── Shipyard.sln
Shipyard is licensed under the MIT License.