$ -weight: 600;">sudo reboot
-weight: 500;">apt -weight: 500;">upgrade
-weight: 500;">restart: always
-weight: 500;">docker-compose.yml
-weight: 500;">restart: always
services: backend: image: your-backend-image -weight: 500;">restart: always # β
restarts automatically after reboot or crash migrations: image: your-migrations-image # no -weight: 500;">restart policy # β
correct β this should run once and exit
services: backend: image: your-backend-image -weight: 500;">restart: always # β
restarts automatically after reboot or crash migrations: image: your-migrations-image # no -weight: 500;">restart policy # β
correct β this should run once and exit
services: backend: image: your-backend-image -weight: 500;">restart: always # β
restarts automatically after reboot or crash migrations: image: your-migrations-image # no -weight: 500;">restart policy # β
correct β this should run once and exit
-weight: 500;">restart: always
-weight: 500;">docker ps
Up 2 days (healthy)
Up 3 minutes
Restarting (1)
Up 2 hours (unhealthy)
Up [days/weeks] (healthy)
cd ~/your-project
-weight: 500;">docker compose config
cd ~/your-project
-weight: 500;">docker compose config
cd ~/your-project
-weight: 500;">docker compose config
-weight: 500;">docker-compose.yml
-weight: 500;">docker compose config
-weight: 500;">docker-compose.yml
-weight: 500;">apt -weight: 500;">upgrade
-weight: 600;">sudo -weight: 500;">apt -weight: 500;">update && -weight: 600;">sudo -weight: 500;">apt -weight: 500;">upgrade -y
The following packages will be upgraded: containerd.io coreutils -weight: 500;">docker-ce -weight: 500;">docker-ce-cli -weight: 500;">docker-ce-rootless-extras -weight: 500;">docker-compose-plugin -weight: 500;">docker-model-plugin gitlab-runner gitlab-runner-helper-images libnftables1 nftables python3-pyasn1
The following packages will be upgraded: containerd.io coreutils -weight: 500;">docker-ce -weight: 500;">docker-ce-cli -weight: 500;">docker-ce-rootless-extras -weight: 500;">docker-compose-plugin -weight: 500;">docker-model-plugin gitlab-runner gitlab-runner-helper-images libnftables1 nftables python3-pyasn1
The following packages will be upgraded: containerd.io coreutils -weight: 500;">docker-ce -weight: 500;">docker-ce-cli -weight: 500;">docker-ce-rootless-extras -weight: 500;">docker-compose-plugin -weight: 500;">docker-model-plugin gitlab-runner gitlab-runner-helper-images libnftables1 nftables python3-pyasn1
containerd.io
-weight: 500;">docker-ce-cli
-weight: 500;">docker-compose-plugin
-weight: 500;">docker compose
libnftables1
gitlab-runner
gitlab-runner-helper-images
python3-pyasn1
-weight: 500;">apt -weight: 500;">upgrade
needrestart
Restarting services... -weight: 500;">systemctl -weight: 500;">restart irqbalance.-weight: 500;">service ssh.-weight: 500;">service rsyslog.-weight: 500;">service ... Service restarts being deferred: -weight: 500;">systemctl -weight: 500;">restart networkd-dispatcher.-weight: 500;">service -weight: 500;">systemctl -weight: 500;">restart systemd-logind.-weight: 500;">service
Restarting services... -weight: 500;">systemctl -weight: 500;">restart irqbalance.-weight: 500;">service ssh.-weight: 500;">service rsyslog.-weight: 500;">service ... Service restarts being deferred: -weight: 500;">systemctl -weight: 500;">restart networkd-dispatcher.-weight: 500;">service -weight: 500;">systemctl -weight: 500;">restart systemd-logind.-weight: 500;">service
Restarting services... -weight: 500;">systemctl -weight: 500;">restart irqbalance.-weight: 500;">service ssh.-weight: 500;">service rsyslog.-weight: 500;">service ... Service restarts being deferred: -weight: 500;">systemctl -weight: 500;">restart networkd-dispatcher.-weight: 500;">service -weight: 500;">systemctl -weight: 500;">restart systemd-logind.-weight: 500;">service
ssh.-weight: 500;">service
systemd-logind
No containers need to be restarted.
No containers need to be restarted.
No containers need to be restarted.
df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 48G 12G 36G 23% /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 48G 12G 36G 23% /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 48G 12G 36G 23% /
-weight: 500;">apt -weight: 500;">upgrade
Total reclaimed space: 4.165GB
Total reclaimed space: 4.165GB
Total reclaimed space: 4.165GB
-weight: 600;">sudo reboot
-weight: 600;">sudo reboot
-weight: 600;">sudo reboot
Connection to [ip] closed by remote host.
ssh -i ~/.ssh/id_rsa ubuntu@YOUR_IP
ssh -i ~/.ssh/id_rsa ubuntu@YOUR_IP
ssh -i ~/.ssh/id_rsa ubuntu@YOUR_IP
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker
β -weight: 500;">docker.-weight: 500;">service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/-weight: 500;">docker.-weight: 500;">service; enabled) Active: active (running) since Mon 2026-03-30 15:55:51 UTC; 5min ago
β -weight: 500;">docker.-weight: 500;">service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/-weight: 500;">docker.-weight: 500;">service; enabled) Active: active (running) since Mon 2026-03-30 15:55:51 UTC; 5min ago
β -weight: 500;">docker.-weight: 500;">service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/-weight: 500;">docker.-weight: 500;">service; enabled) Active: active (running) since Mon 2026-03-30 15:55:51 UTC; 5min ago
Active: active (running)
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable -weight: 500;">docker # ensure it starts on future reboots
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start -weight: 500;">docker # -weight: 500;">start it now
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable -weight: 500;">docker # ensure it starts on future reboots
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start -weight: 500;">docker # -weight: 500;">start it now
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable -weight: 500;">docker # ensure it starts on future reboots
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start -weight: 500;">docker # -weight: 500;">start it now
-weight: 500;">docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc46f84c7bd5 app-backend "uv run uviβ¦" 2 days ago Up 5 minutes (healthy) 8000/tcp app_backend
a3e9a2eeb160 redis:alpine "-weight: 500;">docker-entβ¦" 2 weeks ago Up 5 minutes (healthy) 6379/tcp app_redis
f4afe2edb00c caddy:alpine "caddy run β¦" 4 weeks ago Up 5 minutes (healthy) 80, 443 caddy_proxy
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc46f84c7bd5 app-backend "uv run uviβ¦" 2 days ago Up 5 minutes (healthy) 8000/tcp app_backend
a3e9a2eeb160 redis:alpine "-weight: 500;">docker-entβ¦" 2 weeks ago Up 5 minutes (healthy) 6379/tcp app_redis
f4afe2edb00c caddy:alpine "caddy run β¦" 4 weeks ago Up 5 minutes (healthy) 80, 443 caddy_proxy
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc46f84c7bd5 app-backend "uv run uviβ¦" 2 days ago Up 5 minutes (healthy) 8000/tcp app_backend
a3e9a2eeb160 redis:alpine "-weight: 500;">docker-entβ¦" 2 weeks ago Up 5 minutes (healthy) 6379/tcp app_redis
f4afe2edb00c caddy:alpine "caddy run β¦" 4 weeks ago Up 5 minutes (healthy) 80, 443 caddy_proxy
Up (healthy)
(health: starting)
-weight: 500;">docker compose up
-weight: 500;">docker compose logs [service_name] --tail=50
-weight: 500;">docker compose logs [service_name] --tail=50
-weight: 500;">docker compose logs [service_name] --tail=50
cd ~/your-project
-weight: 500;">docker compose logs -f --tail=20
cd ~/your-project
-weight: 500;">docker compose logs -f --tail=20
cd ~/your-project
-weight: 500;">docker compose logs -f --tail=20
app_gate | 127.0.0.1 - - [30/Mar/2026:16:00:00 +0000] "GET / HTTP/1.1" 200 4140
app_backend | INFO: 127.0.0.1:58562 - "GET /health HTTP/1.1" 200 OK
caddy_proxy | {"level":"info","msg":"received request","uri":"/config/"}
app_redis | * Ready to accept connections tcp
app_gate | 127.0.0.1 - - [30/Mar/2026:16:00:00 +0000] "GET / HTTP/1.1" 200 4140
app_backend | INFO: 127.0.0.1:58562 - "GET /health HTTP/1.1" 200 OK
caddy_proxy | {"level":"info","msg":"received request","uri":"/config/"}
app_redis | * Ready to accept connections tcp
app_gate | 127.0.0.1 - - [30/Mar/2026:16:00:00 +0000] "GET / HTTP/1.1" 200 4140
app_backend | INFO: 127.0.0.1:58562 - "GET /health HTTP/1.1" 200 OK
caddy_proxy | {"level":"info","msg":"received request","uri":"/config/"}
app_redis | * Ready to accept connections tcp
app_worker | redis.exceptions.ConnectionError: Error while reading from redis:6379 : (104, 'Connection reset by peer')
app_worker | 15:56:15: Starting worker for 1 functions: process_message
app_worker | 15:56:15: redis_version=8.6.1 mem_usage=1.38M clients_connected=1
app_worker | redis.exceptions.ConnectionError: Error while reading from redis:6379 : (104, 'Connection reset by peer')
app_worker | 15:56:15: Starting worker for 1 functions: process_message
app_worker | 15:56:15: redis_version=8.6.1 mem_usage=1.38M clients_connected=1
app_worker | redis.exceptions.ConnectionError: Error while reading from redis:6379 : (104, 'Connection reset by peer')
app_worker | 15:56:15: Starting worker for 1 functions: process_message
app_worker | 15:56:15: redis_version=8.6.1 mem_usage=1.38M clients_connected=1
app_backend | sqlalchemy.exc.OperationalError: connection refused
app_backend | [after 5 retries] giving up
app_backend | sqlalchemy.exc.OperationalError: connection refused
app_backend | [after 5 retries] giving up
app_backend | sqlalchemy.exc.OperationalError: connection refused
app_backend | [after 5 retries] giving up
-weight: 600;">sudo gitlab-runner -weight: 500;">status
-weight: 600;">sudo gitlab-runner -weight: 500;">status
-weight: 600;">sudo gitlab-runner -weight: 500;">status
gitlab-runner: Service is running
gitlab-runner: Service is running
gitlab-runner: Service is running
-weight: 600;">sudo gitlab-runner -weight: 500;">start
-weight: 600;">sudo gitlab-runner -weight: 500;">start
-weight: 600;">sudo gitlab-runner -weight: 500;">start
-weight: 600;">sudo reboot
systemd-analyze
systemd-analyze
systemd-analyze
Startup finished in 3.617s (kernel) + 19.608s (userspace) = 23.225s
graphical.target reached after 18.845s in userspace
Startup finished in 3.617s (kernel) + 19.608s (userspace) = 23.225s
graphical.target reached after 18.845s in userspace
Startup finished in 3.617s (kernel) + 19.608s (userspace) = 23.225s
graphical.target reached after 18.845s in userspace
systemd-analyze blame | head -20
systemd-analyze blame | head -20
systemd-analyze blame | head -20
12.186s -weight: 500;">docker.-weight: 500;">service 4.821s cloud-init.-weight: 500;">service 1.204s snapd.-weight: 500;">service 38ms -weight: 500;">docker.socket
12.186s -weight: 500;">docker.-weight: 500;">service 4.821s cloud-init.-weight: 500;">service 1.204s snapd.-weight: 500;">service 38ms -weight: 500;">docker.socket
12.186s -weight: 500;">docker.-weight: 500;">service 4.821s cloud-init.-weight: 500;">service 1.204s snapd.-weight: 500;">service 38ms -weight: 500;">docker.socket
systemd-analyze blame
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q)
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q)
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q)
/app_ftp_bridge: 2026-03-30T15:55:57.766Z
/app_worker: 2026-03-30T15:55:57.695Z
/app_backend: 2026-03-30T15:55:57.646Z
/app_gate: 2026-03-30T15:55:57.830Z
/app_admin: 2026-03-30T15:55:57.742Z
/app_redis: 2026-03-30T15:55:57.794Z
/caddy_proxy: 2026-03-30T15:55:57.615Z
/app_ftp_bridge: 2026-03-30T15:55:57.766Z
/app_worker: 2026-03-30T15:55:57.695Z
/app_backend: 2026-03-30T15:55:57.646Z
/app_gate: 2026-03-30T15:55:57.830Z
/app_admin: 2026-03-30T15:55:57.742Z
/app_redis: 2026-03-30T15:55:57.794Z
/caddy_proxy: 2026-03-30T15:55:57.615Z
/app_ftp_bridge: 2026-03-30T15:55:57.766Z
/app_worker: 2026-03-30T15:55:57.695Z
/app_backend: 2026-03-30T15:55:57.646Z
/app_gate: 2026-03-30T15:55:57.830Z
/app_admin: 2026-03-30T15:55:57.742Z
/app_redis: 2026-03-30T15:55:57.794Z
/caddy_proxy: 2026-03-30T15:55:57.615Z
-weight: 600;">sudo reboot
# --- PRE-REBOOT ---
-weight: 500;">docker ps # check container states
-weight: 500;">docker compose config # validate compose file syntax
df -h / # check available disk space # --- REBOOT ---
-weight: 600;">sudo reboot # initiate the reboot # --- POST-REBOOT ---
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker # confirm daemon is running
-weight: 500;">docker ps # confirm containers are up
-weight: 500;">docker compose logs -f --tail=20 # watch live logs
-weight: 600;">sudo gitlab-runner -weight: 500;">status # check runner (if applicable) # --- TTR MEASUREMENT ---
systemd-analyze # total OS boot time
systemd-analyze blame | head -20 # per--weight: 500;">service boot time breakdown
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q) # exact container -weight: 500;">start timestamps
# --- PRE-REBOOT ---
-weight: 500;">docker ps # check container states
-weight: 500;">docker compose config # validate compose file syntax
df -h / # check available disk space # --- REBOOT ---
-weight: 600;">sudo reboot # initiate the reboot # --- POST-REBOOT ---
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker # confirm daemon is running
-weight: 500;">docker ps # confirm containers are up
-weight: 500;">docker compose logs -f --tail=20 # watch live logs
-weight: 600;">sudo gitlab-runner -weight: 500;">status # check runner (if applicable) # --- TTR MEASUREMENT ---
systemd-analyze # total OS boot time
systemd-analyze blame | head -20 # per--weight: 500;">service boot time breakdown
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q) # exact container -weight: 500;">start timestamps
# --- PRE-REBOOT ---
-weight: 500;">docker ps # check container states
-weight: 500;">docker compose config # validate compose file syntax
df -h / # check available disk space # --- REBOOT ---
-weight: 600;">sudo reboot # initiate the reboot # --- POST-REBOOT ---
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">status -weight: 500;">docker # confirm daemon is running
-weight: 500;">docker ps # confirm containers are up
-weight: 500;">docker compose logs -f --tail=20 # watch live logs
-weight: 600;">sudo gitlab-runner -weight: 500;">status # check runner (if applicable) # --- TTR MEASUREMENT ---
systemd-analyze # total OS boot time
systemd-analyze blame | head -20 # per--weight: 500;">service boot time breakdown
-weight: 500;">docker inspect --format='{{.Name}}: {{.State.StartedAt}}' $(-weight: 500;">docker ps -q) # exact container -weight: 500;">start timestamps
-weight: 500;">docker compose logs [-weight: 500;">service] --tail=50
(health: starting)
-weight: 500;">docker inspect [id]
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">enable -weight: 500;">docker && -weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">start -weight: 500;">docker
-weight: 500;">docker compose logs caddy --tail=50 - Prerequisites - Part 1 β Pre-Reboot Checklist
- Part 2 β Running the Reboot
- Part 3 β Post-Reboot Verification
- Part 4 β Measuring Time to Recovery (TTR) - Quick Reference: All Commands
- Troubleshooting Reference - Ubuntu 22.04 on an OCI Compute instance (ARM or x86)
- Docker + Docker Compose managing your services
- All long-running services configured with -weight: 500;">restart: always in your -weight: 500;">docker-compose.yml
- SSH access to the instance - The OS sends SIGTERM to all running processes, giving them time to shut down cleanly.
- Docker receives the signal and stops all containers gracefully.
- The kernel shuts down and the VM restarts.
- Your SSH session prints Connection to [ip] closed by remote host. and terminates. This is normal. - Active: active (running) β the daemon is running β
- enabled β it is configured to auto--weight: 500;">start on every future boot β
- Every -weight: 500;">service you expect should be present. If one is missing, it crashed on startup.
- STATUS should be Up or Up (healthy). (health: starting) is fine for the first 30 seconds after boot.
- The CREATED timestamp does not reset on reboot β it reflects when the container was first created with -weight: 500;">docker compose up. This is normal.