Skip to content

Commit 66ece24

Browse files
authored
chore: removing need for start_docker.sh instead use mix docker.compose up/down (#179)
1 parent 1846678 commit 66ece24

5 files changed

Lines changed: 274 additions & 2 deletions

File tree

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,20 @@ If you do not have specific requirements on how you would like to start sql serv
222222
in docker, you can use script for this repo.
223223

224224
```bash
225-
$ ./docker-mssql.sh
225+
$ docker compose up -d --profile=<check_profile_in_compose>
226226
```
227227

228+
👉🏻 OR you can let mix task to detect platform you are using and chose best option for you.
229+
230+
```
231+
mix docker.compose up
232+
```
233+
234+
you can see more details about options for `mix docker.compose` taks by running help `mix help docker.compose`
235+
236+
237+
it will do but in some cases you may want to use `mix docker.compose up` so it detects for you which platform you are using, so it will use appropriate image.
238+
228239
If you prefer to install SQL Server directly on your computer, you can find
229240
installation instructions here:
230241

docker-compose.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
services:
2+
tds-mssql-amd64:
3+
profiles: ["mssql_amd64"]
4+
image: mcr.microsoft.com/mssql/server:2022-latest
5+
platform: "linux/amd64"
6+
container_name: tds-mssql-amd64
7+
environment:
8+
ACCEPT_EULA: "Y"
9+
MSSQL_SA_PASSWORD: "some!Password"
10+
MSSQL_PID: "Developer"
11+
healthcheck:
12+
test:
13+
[
14+
"CMD",
15+
"/opt/mssql-tools/bin/sqlcmd",
16+
"-U",
17+
"sa",
18+
"-P",
19+
"Password!",
20+
"-Q",
21+
"select 1",
22+
]
23+
interval: 10s
24+
timeout: 5s
25+
retries: 10
26+
ports:
27+
- "1433:1433"
28+
29+
tds-mssql-arm64:
30+
profiles: ["mssql_arm64"]
31+
image: mcr.microsoft.com/azure-sql-edge:latest
32+
platform: "linux/arm64"
33+
container_name: tds-mssql-arm64
34+
healthcheck:
35+
test:
36+
[
37+
"CMD",
38+
"/opt/mssql-tools/bin/sqlcmd",
39+
"-U",
40+
"sa",
41+
"-P",
42+
"Password!",
43+
"-Q",
44+
"select 1",
45+
]
46+
interval: 10s
47+
timeout: 5s
48+
retries: 10
49+
environment:
50+
ACCEPT_EULA: "1"
51+
MSSQL_SA_PASSWORD: "some!Password"
52+
MSSQL_PID: "Developer"
53+
ports:
54+
- "1433:1433"

lib/mix/tasks/docker.compose.ex

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
defmodule Mix.Tasks.Docker.Compose do
2+
use Mix.Task
3+
4+
@shortdoc "Runs docker compose up/down via Mix with optional platform-aware profiles"
5+
6+
@default_compose "docker-compose.yml"
7+
@amd64_profile "mssql_amd64"
8+
@arm64_profile "mssql_arm64"
9+
10+
@moduledoc """
11+
CLI wrapper around **docker compose** for starting and stopping development services.
12+
13+
## Commands
14+
15+
- `mix docker.compose up`
16+
- `mix docker.compose down`
17+
18+
The `up` command always runs in **detached mode** (`docker compose ... up -d`).
19+
The `down` command stops all services (`docker compose ... down`).
20+
21+
---
22+
23+
## Options
24+
25+
- **`-f`, `--file PATH`**
26+
Use a specific compose file instead of the default:
27+
28+
mix docker.compose up -f docker-compose.test.yml
29+
30+
- **`-p`, `--profile NAME`**
31+
Use a specific compose profile:
32+
33+
mix docker.compose up --profile mssql_amd64
34+
35+
---
36+
37+
## Profile selection rules
38+
39+
If no `-f/--file` is provided:
40+
41+
- `docker-compose.yml` is used
42+
- if no `--profile` is given:
43+
- the profile is auto-selected based on host architecture:
44+
- mssql_arm64 on ARM / Apple Silicon
45+
- mssql_amd64 on x86_64
46+
- if `--profile` is given:
47+
- that profile is used explicitly
48+
49+
If `-f/--file` is provided:
50+
51+
- that compose file is used
52+
- if no `--profile` is given:
53+
- no `--profile` flag is passed to Docker
54+
- if `--profile` is given:
55+
- that profile is passed to Docker
56+
57+
---
58+
59+
## Examples
60+
61+
Basic usage (auto-selected profile):
62+
63+
mix docker.compose up
64+
mix docker.compose down
65+
66+
Custom compose file:
67+
68+
mix docker.compose up -f docker-compose.test.yml
69+
mix docker.compose down -f docker-compose.test.yml
70+
71+
Explicit profile:
72+
73+
mix docker.compose up --profile mssql_amd64
74+
"""
75+
76+
def run(args) do
77+
{opts, rest, has_file?} = parse_args(args)
78+
79+
compose_file = opts[:file] || @default_compose
80+
docker = find_docker!()
81+
82+
profile = select_profile(opts, has_file?)
83+
84+
case rest do
85+
["up"] ->
86+
# up je UVEK detached
87+
run_compose(docker, compose_file, profile, ["up"], true)
88+
89+
["down"] ->
90+
run_compose(docker, compose_file, profile, ["down"], false)
91+
92+
[] ->
93+
Mix.shell().error("""
94+
No command provided. Expected: up | down
95+
96+
Examples:
97+
mix docker.compose up
98+
mix docker.compose down
99+
mix docker.compose up -f docker-compose.dev.yml
100+
""")
101+
102+
unknown ->
103+
Mix.shell().error("Unknown docker.compose command: #{inspect(unknown)}")
104+
end
105+
end
106+
107+
# --------------------------------------------------------------------
108+
# Helpers
109+
# --------------------------------------------------------------------
110+
111+
defp run_compose(docker, compose_file, profile, command, detach?) do
112+
profile_info =
113+
case profile do
114+
nil -> "no profile"
115+
p -> "profile=#{p}"
116+
end
117+
118+
detach_info = if detach?, do: "detached", else: "attached"
119+
120+
IO.puts(
121+
">>> docker compose #{Enum.join(command, " ")} using #{compose_file} (#{profile_info}, #{detach_info})\n"
122+
)
123+
124+
base_args = ["compose", "-f", compose_file]
125+
126+
args =
127+
base_args
128+
|> maybe_add_profile(profile)
129+
# ["compose", "-f", ..., "up" | "down"]
130+
|> Kernel.++(command)
131+
|> maybe_add_detach(detach?)
132+
133+
# output ide direktno na STDOUT, ne koristimo ga u kodu
134+
{_, status} = System.cmd(docker, args, into: IO.stream(:stdio, :line))
135+
136+
if status != 0 do
137+
Mix.raise("docker compose #{Enum.join(command, " ")} failed with exit #{status}.")
138+
end
139+
end
140+
141+
defp maybe_add_profile(args, nil), do: args
142+
defp maybe_add_profile(args, profile), do: args ++ ["--profile", profile]
143+
144+
defp maybe_add_detach(args, true), do: args ++ ["-d"]
145+
defp maybe_add_detach(args, false), do: args
146+
147+
defp find_docker! do
148+
case System.find_executable("docker") do
149+
nil -> Mix.raise("Could not find `docker` executable in PATH")
150+
path -> path
151+
end
152+
end
153+
154+
# vraćamo i flag da li je prosleđen :file (da znamo da li je custom ili default)
155+
defp parse_args(args) do
156+
{opts, rest, _invalid} =
157+
OptionParser.parse(
158+
args,
159+
switches: [
160+
file: :string,
161+
profile: :string
162+
],
163+
aliases: [
164+
f: :file,
165+
p: :profile
166+
]
167+
)
168+
169+
has_file? = Keyword.has_key?(opts, :file)
170+
{opts, rest, has_file?}
171+
end
172+
173+
defp select_profile(opts, has_file?) do
174+
case opts[:profile] do
175+
# user eksplicitno prosledio profil → uvek koristimo
176+
profile when is_binary(profile) ->
177+
profile
178+
179+
# nema --profile
180+
nil ->
181+
if has_file? do
182+
# custom -f → default je "bez profila"
183+
nil
184+
else
185+
# default file → auto-detekcija arhitekture
186+
arch =
187+
:erlang.system_info(:system_architecture)
188+
|> List.to_string()
189+
190+
cond do
191+
String.contains?(arch, "arm") or String.contains?(arch, "aarch64") ->
192+
@arm64_profile
193+
194+
true ->
195+
@amd64_profile
196+
end
197+
end
198+
end
199+
end
200+
end

mix.exs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ defmodule Tds.Mixfile do
1818
tds_encoding: [
1919
mode: if(Mix.env() == :prod, do: :release, else: :debug)
2020
]
21+
],
22+
preferred_cli_env: [
23+
test: :test
2124
]
2225
]
2326
end
@@ -39,7 +42,8 @@ defmodule Tds.Mixfile do
3942
{:ex_doc, "~> 0.19", only: :docs},
4043
{:excoding, "~> 0.1", optional: true, only: :test},
4144
{:tzdata, "~> 1.0", optional: true, only: :test},
42-
{:table, "~> 0.1.0", optional: true}
45+
{:table, "~> 0.1.0", optional: true},
46+
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}
4347
]
4448
end
4549

mix.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
%{
2+
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
23
"castore": {:hex, :castore, "1.0.14", "4582dd7d630b48cf5e1ca8d3d42494db51e406b7ba704e81fbd401866366896a", [:mix], [], "hexpm", "7bc1b65249d31701393edaaac18ec8398d8974d52c647b7904d01b964137b9f4"},
34
"certifi": {:hex, :certifi, "2.15.0", "0e6e882fcdaaa0a5a9f2b3db55b1394dba07e8d6d9bcad08318fb604c6839712", [:rebar3], [], "hexpm", "b147ed22ce71d72eafdad94f055165c1c182f61a2ff49df28bcc71d1d5b94a60"},
5+
"credo": {:hex, :credo, "1.7.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"},
46
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
57
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
68
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
79
"ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"},
810
"excoding": {:hex, :excoding, "0.1.5", "779aab7fef0dfe57f2b1d41c1820fd66483e2b2a3ccd96805f1656d513910051", [:mix], [{:rustler, ">= 0.0.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.5", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}], "hexpm", "db66ee44caf37528887e380a900dc5e234bd57925fc9d91e8c4b0d1ad1700ae1"},
11+
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
912
"hackney": {:hex, :hackney, "1.24.1", "f5205a125bba6ed4587f9db3cc7c729d11316fa8f215d3e57ed1c067a9703fa9", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "f4a7392a0b53d8bbc3eb855bdcc919cd677358e65b2afd3840b5b3690c4c8a39"},
1013
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
1114
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},

0 commit comments

Comments
 (0)