Skip to content

Admin console ​

The console lives at Admin, Containers, Console, or directly at /admin/containers/app.

It is a standalone page. It does not use the CTFd admin theme or Bootstrap, so its look is independent of whichever theme the CTF is running. It uses the admin session for authentication, which means only administrators can open it.

The older Bootstrap pages are still available under Instances (classic), Settings, Cheat Logs, and Import in the same menu. They show the same data and remain as a fallback.

The sidebar shows the sections, a live Docker status indicator, the Docker version, and a link to the classic view.

If the Docker indicator is red, the plugin cannot reach the daemon. Open the Settings tab and check the connection.

Instances tab ​

Instances tab

Summary cards ​

CardMeaning
RunningInstances with a live container
ProvisioningInstances the plugin is still starting
SolvedInstances where the player submitted the correct flag
ErrorInstances whose container failed to start or failed to stop
TotalAll instance rows in the database
Free portsPorts still available in the configured range

A low Free ports number is the earliest warning that the port range needs to grow. Ports are released when an instance stops.

Filters ​

  • Status: running, provisioning, solved, stopped, or error, or all.
  • Challenge ID: restrict to one challenge.
  • Limit: how many rows to load.

Table columns ​

ColumnNotes
ChallengeLinks to the challenge in the admin panel
AccountTeam id in team mode, user id in user mode
StatusColoured badge, see the lifecycle table below
ContainerFirst 12 characters of the Docker container id
PortsThe primary published port
ExpiresRemaining time and the local expiry time
RenewalsHow many extensions the account has used

Row actions ​

  • Logs opens the last 500 lines of container output in a modal.
  • Stop stops the container and keeps the instance record with status stopped.
  • Delete stops the container and removes the instance row and its dependent rows. It asks for confirmation first.

Container logs

Bulk actions ​

Select rows with the checkboxes, then use Delete selected. Emergency stop stops every running container at once and keeps the records so you can see what was running.

Every destructive action asks for confirmation in an inline dialog. No browser dialog is used.

Confirmation dialog

Maintenance ​

ButtonEffect
Clean expiredRuns the expiry sweep immediately instead of waiting for the next scheduled pass
Prune old recordsDeletes stopped, solved, and errored instance records older than the retention setting, and removes containers that no longer have a row
Delete solved recordsRemoves every instance row with status solved

Docker panel ​

Shows the socket in use, the daemon version, the number of running and total containers, and the number of images.

Settings tab ​

Every plugin setting, grouped by purpose. The full reference is in configuration.md.

Settings tab

The Test connection, Demo cheat alert, and Demo error alert buttons send a message to the webhook URL currently typed in the field, so you can validate it before saving.

Cheat logs tab ​

Lists every detected flag reuse: when it happened, on which challenge, who submitted it, who owned the flag, and the source IP.

Cheat logs

The table is paginated. Account names are resolved in bulk, so the page stays fast even with a long history.

Audit log tab ​

The audit trail records what the plugin did, not just what players did. It is the place to look when something behaved unexpectedly.

Audit log

Filter by event type, severity, or search event names and IP addresses.

Event typeWritten when
instance_createdThe database row is created, before Docker is contacted
instance_startedThe container is running and its ports are known
instance_renewedA player extends the expiry
instance_stopped_manualA player clicks Terminate
instance_stopped_expiredThe timer ran out
instance_stopped_solvedThe flag was correct
instance_stopped_adminAn admin stopped it
instance_stopped_admin_deleteDeleted from the console
instance_stopped_admin_bulk_deleteRemoved by a bulk delete
instance_stopped_emergency_stopRemoved by Emergency stop
instance_stopped_challenge_deletedThe challenge itself was deleted
flag_submitted_correctA flag was accepted
flag_reuse_detectedAnother account's flag was submitted

Severity is info, warning, error, or critical. Reuse detections are warning when nothing was banned and critical when the auto-ban threshold triggered.

The details column holds the event specific payload as JSON, for example the container id, the port mapping, or the flag owner account.

Instance rows are deleted after the retention period, and API keys are never included in the audit payload.

Import tab ​

Import

A drag and drop area for a CSV or Excel file, a button to download the CSV template, and a per-row report after the import. See import.md.

Instance lifecycle ​

StatusMeaning
pendingRow created, provisioning not started
provisioningDocker is being asked to start the container
runningContainer is up, connection details are recorded
stoppingA stop is in progress
stoppedContainer stopped, or it expired
solvedThe player submitted the correct flag
errorProvisioning or stopping failed, details are in the record

API endpoints used by the console ​

All of them require an admin session and the CSRF token.

MethodPathPurpose
GET/admin/containers/api/statsCounts per status and free ports
GET/admin/containers/api/instancesList instances with filters
DELETE/admin/containers/api/instances/<id>Delete one instance
POST/admin/containers/api/instances/<id>/stopStop one instance
GET/admin/containers/api/instances/<id>/logsContainer output
POST/admin/containers/api/bulk-deleteDelete several instances
POST/admin/containers/api/bulk/emergency-stopStop everything
POST/admin/containers/api/bulk/cleanup-solvedDelete solved rows
GET/admin/containers/api/cheats/pagePaginated reuse detections
GET/admin/containers/api/auditPaginated audit trail
GET, POST/admin/containers/api/configRead or write settings
POST/admin/containers/api/cleanup/expiredRun the expiry sweep
POST/admin/containers/api/cleanup/oldRun the retention job
GET/admin/containers/api/imagesImages present on the host
GET/admin/containers/api/docker/healthConnection check
POST/admin/containers/api/notifications/testWebhook test
POST/admin/containers/api/importCSV or Excel import
GET/admin/containers/download-templateCSV template

Note for anyone writing an integration: CTFd only validates the CSRF-Token header on requests that declare Content-Type: application/json. A POST with no body must still send that content type, otherwise the request is treated as a form submission and rejected with 403.

Classic pages ​

The original Bootstrap pages are kept for compatibility and for anyone who prefers them.

Classic instances page

Classic settings page

Classic cheat log page

Classic import page

Released under the MIT License.