Call a lua function - the C++ way
As your code goes everything i believe is fine. Define the template, define overloads and combine. Some things i've noticed that might be arguable:


Is it possible that your script will have zero arguments? For example a script with id = N denotes print last command or show commands history. If yes, your code wont compile since       

template&lt;typename T&gt;   
void push(T &amp;&amp; arg) {
   _push(std::forward&lt;T&gt;(arg));
}


doesnt accept zero arguments. Perhaps replace it with zero arg overload?

template&lt;typename T&gt;
void push() {
    // cout &lt;&lt; "All parameters passed to Lua! [Empty args case]\n";  
}

Also as Args &amp;&amp; ... other can actually be zero length there's a question of which will be called template&lt;typename T&gt; void push(T &amp;&amp; arg) or template&lt;typename T, typename ... Args&gt; void push(T &amp;&amp; arg, Args &amp;&amp; ... other). Since push(std::forward&lt;Args&gt;(other)...) can not compile with 0 args, then the first overload will get called. I'd call that a bit misleading if somebody else has to work with your code.
The run_script func is packed with expressions which could potentially fail. So i'd probably try to encapsulate each step into its own method and move the _run() to the zero template push. 

template&lt;typename T&gt;
void push() {
    // cout &lt;&lt; "All parameters passed to Lua! [Empty args case]\n";
    _run(params);     
}


That way if push&lt;T&gt;() gets called you're sure all the parameters were passed to interpreter.
Question arises here is how do you pass params to zero arg push? The topic says C++ way and that means OOP. Imo if you're asking about the C++ style then perhaps you should encapsulate your logic and provide an interface to the user. So go for a class which would hold the arg number as a private member and handle the actual processing of different types. Perhaps two classes one for command and one for processing it. That way it will be easier to scale.
And before doing that i'd think about the actual use of your application:  


Will somebody else will be using it?  
Will it be used in a multithreaded environment?  
What guarantees for the user do you want to provide?  

Your entry function bool run_script is supposed to return true or false i guess depending on how the execution of the script went. Does it really boil down to two outcomes? Are you giving a guarantee that the code would execute no matter what? Perhaps a enum class would suit better.
Your lua_pushstring(L, arg) and lua_pushinteger(L, arg) all hold some L - so seems only fair to hide it somewhere in the class as a private member as well as arg num.  
Are you sure that you'll know all your types at compile time? What if somebody passes a double? There are more elegant ways to check the type being passed but this will do:  

template &lt;class A, class B&gt;
struct eq {
   static const bool result = false;
};

template&lt;class A&gt; struct eq&lt;A, A&gt; {
    static const bool result = true;
};


and use     

if (!eq&lt;int, A&gt;::result) {
    //...unsupported type error
} 



p.s. great project btw. A while a go I've used sockets in Lua and C++ to communicate. So if your code is online I'd love to check it out.