I don't believe there's a Docker-native way of doing this. However, there is a general Linux tool that can re-attach terminals: reptyr. Here's an example of how to use it in Docker.
First, to show this, create a test container with a non-shell process as PID 1.
docker run -d ubuntu sleep 1h
Run docker ps to get the container ID.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
15d0d2c918be ubuntu "sleep 1h" 3 seconds ago Up 2 seconds vigilant_raman
Next, get a shell inside it.
docker exec -it 15d0d2c918be bash
Now, to mark the shell so we know if we got back to the right one, run this command:
root@15d0d2c918be:/# export PS1='findme> '
findme>
This is the shell we're going to try to get back. Detach with Ctrl-P, Ctrl-Q.
Next, get another shell.
docker exec -it 15d0d2c918be bash
Next, install reptyr. This step is Ubuntu-specific; if you use a different OS for your container you'll need to use something else.
root@15d0d2c918be:/# apt-get update
[...]
root@15d0d2c918be:/# apt-get install reptyr
[...]
Next, find the PID of the process to reattach. You're looking for a low-numbered bash process. (Or whichever shell you're using.)
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 sleep 1h
7 pts/0 Ss+ 0:00 bash
15 pts/1 Ss 0:00 bash
269 pts/1 R+ 0:00 ps -ax
We want to attach to PID 7. (PID 15 is our own process ID. You can check the process ID of the current shell by running echo $$.)
Next, create a file at /dev/console. It seems that this step is only necessary when PID 1 is not a console. If the Docker container was launched with a tty, then this step is not required. If you skip this, you'll get the error [-] Unable to stat /dev/console from repytr.
touch /dev/console
Next, get the console back. Use the PID you found previously.
root@15d0d2c918be:/# reptyr 7
[-] Timed out waiting for child stop.
findme>
And now you have the original shell back.