Add container create page from the containers list with always-pull.
Release rolling / release (push) Successful in 8m24s
Release rolling / release (push) Successful in 8m24s
Adds a dedicated blank create form (name, image, always pull, ports, auto-remove, advanced settings) separate from template Deploy, reuses deployContainer with pull-if-missing and publish-all-ports support.
This commit is contained in:
@@ -3790,3 +3790,61 @@ option {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add container page */
|
||||
.add-container-page .page-header {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.add-container-page .addc-back-link {
|
||||
font-size: 0.85rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.add-container-page .addc-back-link:hover {
|
||||
color: var(--accent-primary, #2dd4bf) !important;
|
||||
}
|
||||
.add-container-form .info-card {
|
||||
background: rgba(15, 23, 42, 0.65);
|
||||
border: 1px solid rgba(51, 65, 85, 0.85);
|
||||
border-radius: 12px;
|
||||
padding: 1.15rem 1.25rem;
|
||||
}
|
||||
.add-container-form .form-check-input:checked {
|
||||
background-color: var(--pd-accent-primary, #2dd4bf);
|
||||
border-color: var(--pd-accent-primary, #2dd4bf);
|
||||
}
|
||||
.add-container-form .accordion-button:not(.collapsed) {
|
||||
color: var(--pd-accent-primary, #2dd4bf);
|
||||
box-shadow: none;
|
||||
}
|
||||
.add-container-form .accordion-button:focus {
|
||||
box-shadow: none;
|
||||
border-color: rgba(45, 212, 191, 0.35);
|
||||
}
|
||||
.add-container-form .port-mapping-fields,
|
||||
.add-container-form .volume-mount-fields {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.65rem;
|
||||
align-items: flex-end;
|
||||
width: 100%;
|
||||
}
|
||||
.add-container-form .port-field-group,
|
||||
.add-container-form .volume-field-group {
|
||||
flex: 1 1 6rem;
|
||||
min-width: 0;
|
||||
}
|
||||
.add-container-form .port-connector {
|
||||
align-self: center;
|
||||
color: var(--text-muted, #9aa8bc);
|
||||
padding-bottom: 0.35rem;
|
||||
}
|
||||
.addc-sticky-actions {
|
||||
position: sticky;
|
||||
bottom: 0.75rem;
|
||||
z-index: 5;
|
||||
padding: 0.75rem 1rem;
|
||||
background: rgba(15, 17, 23, 0.92);
|
||||
border: 1px solid rgba(51, 65, 85, 0.7);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
+18
-4
@@ -345,11 +345,16 @@ export async function deployContainerWithSteps(args) {
|
||||
/** @type {{ pulledOk: boolean }} */
|
||||
const state = { pulledOk: false }
|
||||
const replace = args.replace === true
|
||||
const fromAdd = args.source === 'add-container'
|
||||
const alwaysPull = args.alwaysPull !== false
|
||||
const jobLabel = replace
|
||||
? `Replace ${args.containerName || 'container'}`
|
||||
: fromAdd
|
||||
? `Create ${args.containerName || 'container'}`
|
||||
: `Deploy ${args.containerName || 'container'}`
|
||||
|
||||
return runJob(
|
||||
replace
|
||||
? `Replace ${args.containerName || 'container'}`
|
||||
: `Deploy ${args.containerName || 'container'}`,
|
||||
jobLabel,
|
||||
[
|
||||
{
|
||||
id: 'validate',
|
||||
@@ -362,7 +367,9 @@ export async function deployContainerWithSteps(args) {
|
||||
}
|
||||
log(`Name=${args.containerName}`)
|
||||
log(`Image=${args.image}`)
|
||||
log(`Always pull image: ${alwaysPull ? 'yes' : 'no (local if present)'}`)
|
||||
if (replace) log('Mode: replace existing container with same name')
|
||||
if (args.publishAllPorts) log('Publish all exposed ports: yes')
|
||||
if (args.ports?.length) log(`Ports: ${args.ports.join(', ')}`)
|
||||
if (args.volumes?.length) log(`Volumes: ${args.volumes.join(', ')}`)
|
||||
if (args.networkMode) log(`Network mode: ${args.networkMode}`)
|
||||
@@ -371,13 +378,19 @@ export async function deployContainerWithSteps(args) {
|
||||
},
|
||||
{
|
||||
id: 'pull',
|
||||
label: 'Pull image (if needed)',
|
||||
label: alwaysPull ? 'Pull image' : 'Resolve image (local or pull)',
|
||||
run: async ({ log }) => {
|
||||
if (args.skipPull) {
|
||||
log('Skip pull (using local image)')
|
||||
state.pulledOk = true
|
||||
return
|
||||
}
|
||||
// alwaysPull=false: let the server decide (local if present, else pull)
|
||||
if (!alwaysPull) {
|
||||
log('Always pull is off — server will use a local image if available')
|
||||
state.pulledOk = false
|
||||
return
|
||||
}
|
||||
log(`Pulling ${args.image}…`)
|
||||
try {
|
||||
await manager.request(Methods.pullImage, { image: args.image })
|
||||
@@ -406,6 +419,7 @@ export async function deployContainerWithSteps(args) {
|
||||
const payload = {
|
||||
...args,
|
||||
skipPull: state.pulledOk === true,
|
||||
alwaysPull,
|
||||
replace: replace === true,
|
||||
}
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user