How to Restart a Docker Container Remotely
To restart a Docker container remotely, SSH into the host and run docker restart <container>. That stops the container gracefully, then starts it again with the same configuration. If you can't reach a terminal, a phone app that talks to your host over SSH does the same thing from a button tap.
That's the short answer. The rest of this covers the flags that matter, how to restart something you can only reach through a bastion, why a container keeps dying after you restart it, and how to avoid the whole ritual with restart policies.
Restart a Docker container remotely over SSH
Most of the time you're one SSH hop away from the Docker daemon. Connect, then restart by name or ID:
ssh deploy@your-server.example.com
docker restart api-gateway
docker restart is really docker stop followed by docker start. The stop sends SIGTERM to PID 1 in the container, waits, then sends SIGKILL if the process is still alive. The default grace period is 10 seconds. If your app needs longer to drain connections or flush writes, bump it:
docker restart -t 30 api-gateway
You can restart several containers in one command. Handy after a config change that touches a few services:
docker restart api-gateway worker cache
If you don't remember the exact name, list what's running first:
docker ps --format '{{.Names}}\t{{.Status}}'
One-liner without an interactive session, useful in scripts or a quick fix from a jump box:
ssh deploy@your-server.example.com 'docker restart api-gateway'
restart vs. stop/start vs. up
These are not interchangeable, and picking the wrong one is how you end up debugging a "restart" that silently reverted your changes.
docker restartreuses the existing container. Same image, same env, same mounts. It does not pick up a new image or a changeddocker-compose.yml.docker stop+docker startis the same thing, just split into two commands so you can inspect state in between.- If you changed the image tag, environment variables, ports, or volumes, a restart won't apply them. You need to recreate the container.
With Compose, recreation is one command:
docker compose up -d api-gateway
Compose compares the running container against the file and recreates it only if something changed. If you pulled a new image, add the pull first:
docker compose pull api-gateway
docker compose up -d api-gateway
So: config unchanged and you just want a clean process restart, use docker restart. Config or image changed, use docker compose up -d.
Restarting through a bastion or private network
Production Docker hosts usually aren't exposed to the open internet. You reach them through a bastion, a VPN, or SSM. The Docker command is identical once you're on the box; getting there is the part that varies.
Jump host in one line with -J:
ssh -J jump@bastion.example.com deploy@10.0.3.14 'docker restart api-gateway'
Older OpenSSH without -J support uses ProxyCommand in ~/.ssh/config:
Host app-prod
HostName 10.0.3.14
User deploy
ProxyJump jump@bastion.example.com
Then ssh app-prod 'docker restart api-gateway' just works. Encode the hops once and you stop retyping them at 3am when something's on fire.
A word on the Docker socket. You may have seen advice to expose the daemon on a TCP port (-H tcp://0.0.0.0:2375) so you can run docker commands remotely without SSH. Don't. An unauthenticated Docker socket is root on the host to anyone who can reach the port. If you genuinely need remote API access, use TLS client certificates or, simpler, tunnel over SSH:
ssh -L 2375:/var/run/docker.sock deploy@your-server.example.com
Then point a local Docker client at the forwarded socket. SSH stays the trust boundary, which is what you want.
Doing it from your phone
The times you actually need to restart a container remotely are rarely the times you have a laptop open. An alert fires during dinner, on a train, in bed. Opening a terminal, unlocking a VPN, and finding the right host under those conditions is slow.
This is the case Docker HQ is built for. It connects to your hosts over the same SSH you already use, lists running containers, and gives you a restart button per container along with logs and a shell. No exposed daemon, no new port, your existing SSH keys. If a container or host goes down, it pushes an alert to your phone so the restart starts from a notification instead of a customer complaint. There's a broader walkthrough in how to manage Docker containers from your phone, and if you frequently need a shell rather than a restart, running docker exec from your phone over SSH covers that path.
When a restart doesn't stick
You restart the container. Seconds later it's down again. Restarting harder won't fix it, the container is doing exactly what it's told: starting, crashing, and (if it has a restart policy) starting again.
Check why it exited:
docker ps -a --filter name=api-gateway
docker inspect api-gateway --format '{{.State.ExitCode}} {{.State.Error}}'
Then read the logs from the last run. --tail keeps it manageable and -t adds timestamps so you can line events up:
docker logs --tail 100 -t api-gateway
Common culprits: a missing environment variable, a dependency (database, cache) that isn't reachable yet, a bad config file mounted in, or the process hitting an OOM kill. For OOM specifically, docker inspect shows OOMKilled: true under .State. That's a memory limit problem, not a restart problem, and no amount of restarting fixes it. Raise the limit or fix the leak.
If the container is in a crash loop under a restart policy, stop the churn while you investigate:
docker stop api-gateway
Then fix the underlying issue and bring it back with docker start or docker compose up -d.
Skip the manual restart: restart policies
The best remote restart is the one that happens automatically before you wake up. Docker restart policies handle the common case of "the process died, just bring it back."
Set one at run time:
docker run -d --restart unless-stopped --name api-gateway myorg/api:latest
Or in Compose:
services:
api-gateway:
image: myorg/api:latest
restart: unless-stopped
The options:
no(default) never restarts.on-failurerestarts only on a non-zero exit code, with an optional max retry count (on-failure:5).alwaysrestarts whenever it stops, including after a daemon or host reboot.unless-stoppedis likealways, except it won't restart a container you deliberately stopped. This is the one most people want.
Apply a policy to an already-running container without recreating it:
docker update --restart unless-stopped api-gateway
Policies use an exponential backoff, so a container that keeps failing won't hammer your host. They don't fix bad code, but they do turn a transient blip, a brief network hiccup or a one-off panic, into a non-event.
One caveat: always and unless-stopped only resume on boot if the Docker daemon itself starts on boot. On systemd hosts, systemctl enable docker handles that. If Docker isn't enabled as a service, your containers won't come back after a reboot no matter what policy they carry.
Frequently asked questions
How do I restart a Docker container without SSH access?
You need some authenticated path to the daemon. If you can't SSH, options are a TLS-secured Docker API, an orchestrator like Kubernetes or Docker Swarm with its own control plane, or a mobile app that holds the SSH connection for you. Do not expose the Docker socket over plain TCP to work around missing SSH, that hands root on the host to anyone who finds the port.
What's the difference between restarting and recreating a container?
docker restart stops and starts the same container with its existing configuration. It won't pick up a new image, changed environment variables, or edited Compose settings. Recreating (docker compose up -d, or docker rm then docker run) builds a fresh container from the current config. Use restart for a clean process bounce, recreate when something in the definition changed.
How do I restart all containers on a host at once?
docker restart $(docker ps -q) restarts every running container. With Compose, docker compose restart bounces everything in the project. Both are blunt instruments, restarting unrelated services can cause its own outage, so prefer naming the specific containers you mean unless you really want the whole host bounced.
Why does my container restart on its own?
It has a restart policy (always, unless-stopped, or on-failure) and the process inside is exiting. Docker is honoring the policy. Check docker logs and the exit code with docker inspect to find why the process dies, then fix that. If you want it to stay down, docker update --restart no <container> removes the policy.
Where to go from here
Pick one host and set unless-stopped on the services that should survive a crash. That alone removes most of the 3am restart pages. For the ones that still need eyes, decide now how you'll reach the host when you're away from your desk, whether that's a saved SSH config with ProxyJump or an app on your phone, because that decision is much easier to make before the alert than after. If you're juggling more than a couple of servers, managing multiple Docker hosts from one place and the Docker HQ pricing page are worth a look.