Frame this nice ASCII-Art

Haskell, 139 bytes

q=length
g x|l<-lines x,m<-maximum$q<$>l,s<-[-1..m]>>"═"='╔':s++"╗\n"++(l>>= \z->"║ "++z++([q z..m]>>" ")++"║\n")++'╚':s++"╝"

As an example I'm framing snowman "12333321".

*Main> putStrLn $ g " _===_\n (O.O)\n/(] [)\\\n ( : )"
╔═════════╗
║  _===_  ║
║  (O.O)  ║
║ /(] [)\ ║
║  ( : )  ║
╚═════════╝

How it works:

bind
  l: input split into lines
  m: maximum line length
  s: m+2 times ═

build top line
prepend left frame to each line, pad with spaces, append right frame
build bottom line.

JavaScript (ES6), 138 bytes

This is 138 bytes in the IBM866 encoding, which at time of writing is still supported in Firefox, but 152 in UTF-8.

s=>`╔${t='═'.repeat(w=2+Math.max(...(a=s.split`
`).map(s=>s.length)))}╗
${a.map(s=>('║ '+s+' '.repeat(w)).slice(0,w+1)).join`║
`}║
╚${t}╝`

Bash, 173 171 150 148 147 bytes, 157 136 134 133 characters

q(){((n=${#2}>n?${#2}:n));};mapfile -tc1 -C q v;for((p=++n+1;p;--p));do z+=═;done;echo ╔$z╗;printf "║ %-${n}s║\n" "${v[@]}";echo ╚$z╝

Multiline:

q() {
    (( n = ${#2} > n ? ${#2} : n))
}
mapfile -tc1 -C q v

for((p=++n+1;p;--p))
do 
    z+=═
done

echo ╔$z╗
printf "║ %-${n}s║\n" "${v[@]}"
echo ╚$z╝

Example execution:

bash -c 'q(){((n=${#2}>n?${#2}:n));};mapfile -tc1 -C q v;for((p=++n+1;p;--p));do z+=═;done;echo ╔$z╗;printf "║ %-${n}s║\n" "${v[@]}";echo ╚$z╝'< bear.txt

Sample run from script:

$ cat bear2.txt 
     (()__(()
     /       \
    ( /    \  \
     \ o o    /
     (_()_)__/ \
    / _,==.____ \
   (   |--|      )
   /\_.|__|'-.__/\_
  / (        /     \
  \  \      (      /
   )  '._____)    /
(((____.--(((____/mrf
$ ./frame< bear2.txt 
╔═══════════════════════╗
║      (()__(()         ║
║      /       \        ║
║     ( /    \  \       ║
║      \ o o    /       ║
║      (_()_)__/ \      ║
║     / _,==.____ \     ║
║    (   |--|      )    ║
║    /\_.|__|'-.__/\_   ║
║   / (        /     \  ║
║   \  \      (      /  ║
║    )  '._____)    /   ║
║ (((____.--(((____/mrf ║
╚═══════════════════════╝