diff --git a/client/src/App.tsx b/client/src/App.tsx
index 30f9f980..e15711cf 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -49,6 +49,7 @@ import useUser from "./apps/Auth/hooks/useUser";
import AccountEmails from "./apps/Auth/pages/Account/AccountEmails";
import { getAuthToken } from "./backend/server";
import AccountTheme from "./apps/Auth/pages/Account/AccountTheme";
+import ContainerPorts from "./apps/Containers/pages/ContainerPorts/ContainerPorts";
const queryClient = new QueryClient();
@@ -179,6 +180,10 @@ function AllRoutes() {
path="/containers/:uuid/environment"
element={}
/>
+ }
+ />
}
diff --git a/client/src/apps/Containers/backend/api.ts b/client/src/apps/Containers/backend/api.ts
index f0bb151f..bc3b3cff 100644
--- a/client/src/apps/Containers/backend/api.ts
+++ b/client/src/apps/Containers/backend/api.ts
@@ -77,6 +77,11 @@ const saveEnv = (id: string, env: EnvVariables) => {
return server.patch(`/containers/${id}/environment`, { env });
};
+const getContainerPorts = async (id: string) => {
+ const { data } = await server.get(`/containers/${id}/ports`);
+ return data;
+};
+
const getDocker = async (id: string) => {
const { data } = await server.get(
`/containers/${id}/docker`
@@ -111,6 +116,7 @@ export const API = {
getLogs,
getContainerEnvironment,
saveEnv,
+ getContainerPorts,
getDockerInfo: getDocker,
recreateDocker,
updateService,
diff --git a/client/src/apps/Containers/hooks/useContainer.tsx b/client/src/apps/Containers/hooks/useContainer.tsx
index 3cc02e14..542285b6 100644
--- a/client/src/apps/Containers/hooks/useContainer.tsx
+++ b/client/src/apps/Containers/hooks/useContainer.tsx
@@ -36,3 +36,15 @@ export function useContainerEnv(id?: string) {
errorEnv: queryEnv.error,
};
}
+
+export function useContainerPorts(id?: string) {
+ const queryPorts = useQuery({
+ queryKey: ["container_ports", id],
+ queryFn: () => API.getContainerPorts(id),
+ });
+ return {
+ ports: queryPorts.data,
+ isLoadingPorts: queryPorts.isLoading,
+ errorPorts: queryPorts.error,
+ };
+}
diff --git a/client/src/apps/Containers/pages/Container/Container.tsx b/client/src/apps/Containers/pages/Container/Container.tsx
index b5c90e31..2ac9dc3c 100644
--- a/client/src/apps/Containers/pages/Container/Container.tsx
+++ b/client/src/apps/Containers/pages/Container/Container.tsx
@@ -25,6 +25,7 @@ import {
Cube,
Gear,
House,
+ ShareNetwork,
TerminalWindow,
Textbox,
Trash,
@@ -107,6 +108,11 @@ export default function ContainerDetails() {
icon={}
link={l(`/containers/${uuid}/environment`)}
/>
+ }
+ link={l(`/containers/${uuid}/ports`)}
+ />
{container?.databases && (
+ Ports
+
+
+
+
+ );
+}
diff --git a/server/apps/containers/app.go b/server/apps/containers/app.go
index a126a98d..b6b71504 100644
--- a/server/apps/containers/app.go
+++ b/server/apps/containers/app.go
@@ -171,6 +171,12 @@ func (a *App) InitializeRouter(r *fizz.RouterGroup) error {
fizz.Response("500", "", nil, nil, map[string]interface{}{"error": "failed to patch container environment"}),
}, containersHandler.PatchEnvironment())
+ containers.GET("/:container_id/ports", []fizz.OperationOption{
+ fizz.ID("getContainerPorts"),
+ fizz.Summary("Get container ports"),
+ fizz.Response("404", "Container not found", nil, nil, map[string]interface{}{"error": "container not found"}),
+ }, containersHandler.GetContainerPorts())
+
containers.GET("/:container_id/events", []fizz.OperationOption{
fizz.ID("eventsContainer"),
fizz.Summary("Get container events"),
diff --git a/server/apps/containers/core/port/handlers.go b/server/apps/containers/core/port/handlers.go
index 8d7534e8..56af6b88 100644
--- a/server/apps/containers/core/port/handlers.go
+++ b/server/apps/containers/core/port/handlers.go
@@ -16,6 +16,7 @@ type (
AddContainerTag() gin.HandlerFunc
GetContainerEnv() gin.HandlerFunc
PatchEnvironment() gin.HandlerFunc
+ GetContainerPorts() gin.HandlerFunc
GetDocker() gin.HandlerFunc
RecreateDocker() gin.HandlerFunc
GetLogs() gin.HandlerFunc
diff --git a/server/apps/containers/core/port/services.go b/server/apps/containers/core/port/services.go
index 912cd377..519f48f6 100644
--- a/server/apps/containers/core/port/services.go
+++ b/server/apps/containers/core/port/services.go
@@ -30,6 +30,7 @@ type (
SetDatabases(ctx context.Context, c *types.Container, databases map[string]uuid.UUID, options map[string]*types.SetDatabasesOptions) error
GetContainerEnv(ctx context.Context, id uuid.UUID) (types.EnvVariables, error)
SaveEnv(ctx context.Context, id uuid.UUID, env types.EnvVariables) error
+ GetContainerPorts(ctx context.Context, id uuid.UUID) (types.Ports, error)
GetAllVersions(ctx context.Context, id uuid.UUID, useCache bool) ([]string, error)
GetContainerInfo(ctx context.Context, id uuid.UUID) (map[string]any, error)
WaitStatus(ctx context.Context, id uuid.UUID, status string) error
diff --git a/server/apps/containers/core/port/services_mock.go b/server/apps/containers/core/port/services_mock.go
index aef3ed7d..e92d078f 100644
--- a/server/apps/containers/core/port/services_mock.go
+++ b/server/apps/containers/core/port/services_mock.go
@@ -94,6 +94,11 @@ func (m *MockContainerService) GetContainerEnv(ctx context.Context, id uuid.UUID
return args.Get(0).(types.EnvVariables), args.Error(1)
}
+func (m *MockContainerService) GetContainerPorts(ctx context.Context, id uuid.UUID) (types.Ports, error) {
+ args := m.Called(ctx, id)
+ return args.Get(0).(types.Ports), args.Error(1)
+}
+
func (m *MockContainerService) RecreateContainer(ctx context.Context, uuid uuid.UUID) error {
args := m.Called(ctx, uuid)
return args.Error(0)
diff --git a/server/apps/containers/core/service/container.go b/server/apps/containers/core/service/container.go
index ab43faba..9933dfe7 100644
--- a/server/apps/containers/core/service/container.go
+++ b/server/apps/containers/core/service/container.go
@@ -623,6 +623,10 @@ func (s *containerService) GetContainerEnv(ctx context.Context, id uuid.UUID) (t
return s.vars.GetContainerVariables(ctx, id)
}
+func (s *containerService) GetContainerPorts(ctx context.Context, id uuid.UUID) (types.Ports, error) {
+ return s.ports.GetContainerPorts(ctx, id)
+}
+
// remapDatabaseEnv remaps the environment variables of a container.
func (s *containerService) remapDatabaseEnv(ctx context.Context, c *types.Container, options map[string]*types.SetDatabasesOptions) error {
for databaseID, databaseContainerID := range c.Databases {
diff --git a/server/apps/containers/handler/container.go b/server/apps/containers/handler/container.go
index e69819da..470eebef 100644
--- a/server/apps/containers/handler/container.go
+++ b/server/apps/containers/handler/container.go
@@ -167,6 +167,17 @@ func (h *containerHandler) PatchEnvironment() gin.HandlerFunc {
}, http.StatusOK)
}
+type GetContainerPortsParams struct {
+ ContainerID uuid.NullUUID `path:"container_id"`
+}
+
+func (h *containerHandler) GetContainerPorts() gin.HandlerFunc {
+ return tonic.Handler(func(ctx *gin.Context, params *GetContainerPortsParams) (types.Ports, error) {
+ return h.containerService.GetContainerPorts(ctx, params.ContainerID.UUID)
+ }, http.StatusOK)
+
+}
+
func (h *containerHandler) GetDocker() gin.HandlerFunc {
return tonic.Handler(func(ctx *gin.Context, params *GetContainerParams) (map[string]any, error) {
return h.containerService.GetContainerInfo(ctx, params.ContainerID.UUID)