如何用Nomad在无Docker的Windows服务器执行MySQL初始化命令?
First, let's break down why your current setup isn't working: Nomad's exec driver on Windows runs the specified executable directly, not through a shell like cmd.exe or PowerShell. That means special shell syntax like the input redirect < gets passed as a literal argument to mysql instead of being interpreted as "read from this file"—which is why your parameters aren't behaving as expected.
Good news: Nomad absolutely supports one-time database initialization tasks! You just need to adjust your approach to work with how the exec driver operates. Here are two solid solutions:
Solution 1: Wrap the Command in cmd.exe to Handle Shell Syntax
Since Windows shell features like redirects only work when run through cmd.exe, use it as your base command and pass the full mysql command as an argument with /c (this tells cmd to execute the string and exit):
job "gavin-setup" { datacenters = ["dc1"] group "gavin-setup-group" { task "setup" { driver = "exec" config = { command = "cmd.exe" args = [ "/c", "mysql -hlocalhost -ugavin -pgavin_secret gavin_database < C:\\gavin\\config\\create.sql" ] } # Ensure this task only runs once (no retries if it fails) restart { attempts = 0 mode = "fail" } } } }
This way, cmd.exe parses the < redirect and feeds the contents of create.sql into mysql exactly as you intended.
Solution 2: Use MySQL's Built-in --init-file Parameter (Cleaner Approach)
Instead of relying on shell redirects, use MySQL's native --init-file flag to tell it to execute the SQL script directly. This avoids needing to wrap the command in a shell entirely, which is more straightforward:
job "gavin-setup" { datacenters = ["dc1"] group "gavin-setup-group" { task "setup" { driver = "exec" config = { command = "mysql" args = [ "-hlocalhost", "-ugavin", "-pgavin_secret", "gavin_database", "--init-file=C:\\gavin\\config\\create.sql" ] } # Prevent repeated execution of the initialization restart { attempts = 0 mode = "fail" } } } }
This is my go-to method because it eliminates potential edge cases with command escaping and keeps the task configuration focused on the actual database operation.
Bonus: Ensure Initialization Runs After MySQL is Ready
If you're deploying MySQL alongside this initialization task, use Nomad's depends_on block to guarantee the setup only runs once MySQL is healthy and accepting connections. Here's a combined example:
job "mysql-and-setup" { datacenters = ["dc1"] group "mysql-group" { task "mysql" { driver = "exec" config = { command = "mysqld" args = ["--defaults-file=C:\\gavin\\config\\my.ini"] } # Define a service with a health check to confirm MySQL is up service { name = "mysql" port = "3306" check { type = "tcp" port = "3306" interval = "10s" timeout = "2s" } } } task "setup" { driver = "exec" config = { command = "mysql" args = [ "-hlocalhost", "-ugavin", "-pgavin_secret", "gavin_database", "--init-file=C:\\gavin\\config\\create.sql" ] } # Wait for MySQL's health check to pass before running initialization depends_on { task = "mysql" condition = "healthy" } restart { attempts = 0 mode = "fail" } } } }
All these approaches let you run one-time database initialization tasks with Nomad's exec driver on Windows—no Docker required.
内容的提问来源于stack exchange,提问作者Gavin Palmer

