From 009b29852033d4bb0b35657798b619e132df6787 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:09:05 +0200 Subject: [PATCH] chore(dev): replace Spin with docker compose for local dev Drop Spin from docs and helper scripts; run the stack and container exec via docker compose with docker-compose.yml and docker-compose.dev.yml. Update firewall-delegation tests to match the new commands. --- AGENTS.md | 4 +- DEVELOPMENT.md | 22 +++---- dev/coold-dev.md | 2 +- scripts/dev.sh | 62 +++++++++---------- scripts/railpack-smoke.sh | 2 +- scripts/run | 20 +++--- .../DevScriptFirewallDelegationTest.php | 16 ++--- 7 files changed, 61 insertions(+), 67 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e35c5d74fb..a96bbf59a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,8 +16,8 @@ Docker Compose-based dev setup with services: coolify (app), postgres, redis, so ```bash # Start dev environment (uses docker-compose.dev.yml) -spin up # or: docker compose -f docker-compose.dev.yml up -d -spin down # stop services +docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d +docker compose -f docker-compose.yml -f docker-compose.dev.yml down # stop services # Two local Coolify instances (isolated stacks; server transfer / multi-control-plane) ./scripts/dev-instances up # a:8000 + b:8001 (uses npm run build for CSS/JS) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 910657159b..bdcddb06a0 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -34,8 +34,6 @@ Follow the steps below for your operating system: - Download and install [Docker Desktop for Windows](https://docs.docker.com/desktop/install/windows-install/?ref=coolify) - Ensure WSL2 backend is enabled in Docker Desktop settings -2. Install Spin: - - Follow the instructions to install Spin on Windows from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-windows#download-and-install-spin-into-wsl2?ref=coolify) @@ -48,8 +46,6 @@ Follow the steps below for your operating system: - Docker Desktop: - Download and install [Docker Desktop for Mac](https://docs.docker.com/desktop/install/mac-install/?ref=coolify) -2. Install Spin: - - Follow the instructions to install Spin on MacOS from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-macos/#download-and-install-spin?ref=coolify) @@ -62,22 +58,20 @@ Follow the steps below for your operating system: - Docker Desktop: - If you want a GUI, you can use [Docker Desktop for Linux](https://docs.docker.com/desktop/install/linux-install/?ref=coolify) -2. Install Spin: - - Follow the instructions to install Spin on Linux from the [Spin documentation](https://serversideup.net/open-source/spin/docs/installation/install-linux#configure-docker-permissions?ref=coolify) ## 2. Verify Installation (Optional) -After installing Docker (or Orbstack) and Spin, verify the installation: +After installing Docker (or Orbstack), verify the installation: 1. Open a terminal or command prompt 2. Run the following commands: ```bash docker --version - spin --version + docker compose version ``` - You should see version information for both Docker and Spin. + You should see version information for Docker and Docker Compose. ## 3. Fork and Setup Local Repository @@ -105,7 +99,7 @@ After installing Docker (or Orbstack) and Spin, verify the installation: 1. In the Code Editor, locate the `.env.development.example` file in the root directory of your local Coolify repository. 2. Duplicate the `.env.development.example` file and rename the copy to `.env`. 3. Open the new `.env` file and review its contents. Adjust any environment variables as needed for your development setup. -4. If you encounter errors during database migrations, update the database connection settings in your `.env` file. Use the IP address or hostname of your PostgreSQL database container. You can find this information by running `docker ps` after executing `spin up`. +4. If you encounter errors during database migrations, update the database connection settings in your `.env` file. Use the IP address or hostname of your PostgreSQL database container. You can find this information by running `docker ps` after executing `docker compose -f docker-compose.yml -f docker-compose.dev.yml up`. 5. Save the changes to your `.env` file. @@ -113,7 +107,7 @@ After installing Docker (or Orbstack) and Spin, verify the installation: 1. Open a terminal in the local Coolify directory. 2. Run the following command in the terminal (leave that terminal open): ```bash - spin up + docker compose -f docker-compose.yml -f docker-compose.dev.yml up ``` > [!NOTE] @@ -121,11 +115,11 @@ After installing Docker (or Orbstack) and Spin, verify the installation: 3. If you encounter permission errors, especially on macOS, use: ```bash - sudo spin up + sudo docker compose -f docker-compose.yml -f docker-compose.dev.yml up ``` > [!NOTE] -> If you change environment variables afterwards or anything seems broken, press Ctrl + C to stop the process and run `spin up` again. +> If you change environment variables afterwards or anything seems broken, press Ctrl + C to stop the process and run `docker compose -f docker-compose.yml -f docker-compose.dev.yml up` again. ## 6. Start Development @@ -196,7 +190,7 @@ If you encounter issues or break your database or something else, follow these s 5. Start Coolify again: ```bash - spin up + docker compose -f docker-compose.yml -f docker-compose.dev.yml up ``` 6. Run database migrations and seeders: diff --git a/dev/coold-dev.md b/dev/coold-dev.md index 751f1569ce..5bcb215c77 100644 --- a/dev/coold-dev.md +++ b/dev/coold-dev.md @@ -61,7 +61,7 @@ The generated bootstrap command uses the container CLI, the repo-local copy of the Lima SSH key, and dev WireGuard endpoint overrides, for example: ```bash -spin exec -T coolify /usr/local/bin/coolify init bootstrap \ +docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify /usr/local/bin/coolify init bootstrap \ --nodes "coold-dev.local,coold-dev-2.local" \ --ssh-key "/var/www/html/.dev/lima/ssh_key" \ --ssh-user "coolify" \ diff --git a/scripts/dev.sh b/scripts/dev.sh index d20e76a1c2..7f337769d5 100755 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -181,7 +181,7 @@ sync_lima_hosts_into_coolify_container() { done echo "==> Syncing Lima .local host records into the Coolify container..." - spin exec -T -u root coolify sh -lc ' + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T -u root coolify sh -lc ' set -e records=/tmp/coolify-lima-hosts next=/tmp/coolify-hosts-next @@ -316,7 +316,7 @@ coolify_bootstrap_command() { endpoint_overrides="$(coolify_wg_endpoint_overrides_arg)" || return 1 cat < coolify CLI is provided by the Coolify dev container." - spin exec -T coolify "$(coolify_cli_bin)" --version + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify "$(coolify_cli_bin)" --version ;; path) coolify_cli_bin @@ -422,7 +422,7 @@ coolify_dev() { coolify_bootstrap_command ;; run) - exec spin exec -T coolify "$(coolify_cli_bin)" "$@" + exec docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify "$(coolify_cli_bin)" "$@" ;; -h|--help|help) cat <<'USAGE' @@ -504,7 +504,7 @@ mint_host_jwt_for_host() { local output for attempt in $(seq 1 "$attempts"); do - if output="$(spin exec -T coolify php artisan flux:dev "$host_id" 2>&1)"; then + if output="$(docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan flux:dev "$host_id" 2>&1)"; then printf '%s\n' "$output" | tail -n 1 return 0 fi @@ -552,7 +552,7 @@ follow_logs() { done fi - spin logs -f + docker compose -f docker-compose.yml -f docker-compose.dev.yml logs -f } sync_v5_dev_lima_servers() { @@ -572,10 +572,10 @@ sync_v5_dev_lima_servers() { done echo "==> Running pending migrations before syncing v5 dev Lima state..." - spin exec -T coolify php artisan migrate --force + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan migrate --force echo "==> Seeding dev Lima VM(s) into v5 clusters/servers..." - spin exec -T \ + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T \ -e COOLIFY_CLI_SSH_USER="$ssh_user" \ coolify php artisan v5:sync-dev-lima-servers \ "${server_args[@]}" @@ -613,7 +613,7 @@ up() { local follow_dev_logs local count local naked=false - local spin_args=() + local compose_args=() coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)" follow_dev_logs="$(read_coolify_env COOLIFY_DEV_FOLLOW_LOGS true)" count="$(coold_vm_count)" @@ -625,14 +625,14 @@ up() { shift ;; *) - spin_args+=("$1") + compose_args+=("$1") shift ;; esac done if [ "$coold_vm_enabled" != "false" ]; then - echo "==> Starting ${count} Coolify coold VM(s) before Spin..." + echo "==> Starting ${count} Coolify coold VM(s) before Docker Compose..." for index in $(seq 1 "$count"); do coold_vm_up_with_retry "$index" done @@ -640,17 +640,17 @@ up() { echo "==> COOLIFY_COOLD_VM_ENABLED=false; skipping coold VM." fi - echo "==> Starting Coolify Docker stack with Spin..." + echo "==> Starting Coolify Docker stack with Docker Compose..." prepare_coold_asset_cache_bust if [ "$COOLD_ASSETS_CHANGED" = "changed" ]; then echo "==> Coold nightly assets changed; rebuilding the Coolify dev image..." - COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" spin build coolify + COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" docker compose -f docker-compose.yml -f docker-compose.dev.yml build coolify fi - if [ "${#spin_args[@]}" -gt 0 ]; then - COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" spin up -d "${spin_args[@]}" + if [ "${#compose_args[@]}" -gt 0 ]; then + COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d "${compose_args[@]}" else - COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" spin up -d + COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d fi if [ "$coold_vm_enabled" != "false" ]; then @@ -674,7 +674,7 @@ up() { fi if [ "$follow_dev_logs" = "false" ]; then - echo "==> Dev environment is ready. Use 'spin logs -f' or 'scripts/coold-vm.sh logs-agent' to follow logs." + echo "==> Dev environment is ready. Use 'docker compose -f docker-compose.yml -f docker-compose.dev.yml logs -f' or 'scripts/coold-vm.sh logs-agent' to follow logs." return fi @@ -685,7 +685,7 @@ down() { local coold_vm_enabled local stop_coold_vm local cleanup=false - local spin_args=() + local compose_args=() coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)" stop_coold_vm="$(read_coolify_env COOLIFY_COOLD_VM_STOP_ON_DOWN false)" @@ -696,7 +696,7 @@ down() { shift ;; *) - spin_args+=("$1") + compose_args+=("$1") shift ;; esac @@ -709,11 +709,11 @@ down() { done fi - echo "==> Stopping Coolify Docker stack with Spin..." - if [ "${#spin_args[@]}" -gt 0 ]; then - spin down "${spin_args[@]}" + echo "==> Stopping Coolify Docker stack with Docker Compose..." + if [ "${#compose_args[@]}" -gt 0 ]; then + docker compose -f docker-compose.yml -f docker-compose.dev.yml down "${compose_args[@]}" else - spin down + docker compose -f docker-compose.yml -f docker-compose.dev.yml down fi if [ "$cleanup" = "true" ]; then @@ -1063,7 +1063,7 @@ example_nginx() { refresh_test_host_key() { echo "==> Refreshing /tmp/testhostkey inside coolify..." - spin exec -T coolify php artisan tinker --execute='file_put_contents("/tmp/testhostkey", \App\Models\PrivateKey::query()->where("name", "Testing Host Key")->sole()->private_key); chmod("/tmp/testhostkey", 0600);' + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan tinker --execute='file_put_contents("/tmp/testhostkey", \App\Models\PrivateKey::query()->where("name", "Testing Host Key")->sole()->private_key); chmod("/tmp/testhostkey", 0600);' } recreate_naked_lima_vm() { @@ -1104,7 +1104,7 @@ fresh() { COOLIFY_DEV_FOLLOW_LOGS=false up echo "==> Refreshing Coolify database with seed data..." - spin exec -T coolify php artisan migrate:fresh --seed --force + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan migrate:fresh --seed --force if [ "$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)" != "false" ]; then echo "==> Re-syncing seeded v5 Lima servers after DB refresh..." @@ -1115,7 +1115,7 @@ fresh() { refresh_test_host_key echo "==> Restarting Horizon so workers use the latest code..." - spin exec -T coolify php artisan horizon:terminate || true + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan horizon:terminate || true echo "==> Fresh dev environment is ready." limactl list | grep -E 'NAME|coold-dev|coolify-naked-test' || true @@ -1123,14 +1123,14 @@ fresh() { usage() { cat <<'USAGE' -Usage: scripts/dev.sh [spin args] +Usage: scripts/dev.sh [docker compose -f docker-compose.yml -f docker-compose.dev.yml args] Commands: - up Start the coold VM, Spin stack, and dev coold agent + up Start the coold VM, Docker Compose stack, and dev coold agent fresh Recreate coold/naked Lima VMs, refresh DB, seed, sync v5 dev servers up --naked - Start the coold VM(s) and Spin stack only; skip host bootstrap so /v5 can bootstrap - down Stop the dev coold agent and Spin stack + Start the coold VM(s) and Docker Compose stack only; skip host bootstrap so /v5 can bootstrap + down Stop the dev coold agent and Docker Compose stack down --cleanup Stop the dev stack, then delete the coold Lima VM(s) and VM-local state shell [hostname] diff --git a/scripts/railpack-smoke.sh b/scripts/railpack-smoke.sh index 0fe7573164..cfcc311a3f 100755 --- a/scripts/railpack-smoke.sh +++ b/scripts/railpack-smoke.sh @@ -9,7 +9,7 @@ # build inputs landed correctly. Optionally curls the FQDN. # # Requires: -# - Dev stack running: spin up (or docker compose -f docker-compose.dev.yml up -d) +# - Dev stack running: docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d # - Seeder run: php artisan db:seed --class=DevelopmentRailpackExamplesSeeder # - Personal token: PersonalAccessTokenSeeder run (creates Bearer 'root') # - jq, curl available on host diff --git a/scripts/run b/scripts/run index 466b045306..701895c349 100755 --- a/scripts/run +++ b/scripts/run @@ -21,10 +21,10 @@ function help { } function logs { - docker exec -t coolify tail -f storage/logs/laravel.log + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify tail -f storage/logs/laravel.log } function test { - docker exec -t coolify php artisan test --testsuite=Feature -p + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify php artisan test --testsuite=Feature -p } function sync:bunny { @@ -32,33 +32,33 @@ function sync:bunny { } function db:reset { - bash spin exec -u www-data coolify php artisan migrate:fresh --seed + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -u www-data coolify php artisan migrate:fresh --seed } function db:reset-prod { - bash spin exec -u www-data coolify php artisan migrate:fresh --force --seed --seeder=ProductionSeeder || + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -u www-data coolify php artisan migrate:fresh --force --seed --seeder=ProductionSeeder || php artisan migrate:fresh --force --seed --seeder=ProductionSeeder } function coolify { - bash spin exec -u www-data coolify sh + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -u www-data coolify sh } function coolify:root { - bash spin exec coolify sh + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec coolify sh } function coolify:proxy { - docker exec -ti coolify-proxy sh + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec coolify-proxy sh } function redis { - docker exec -ti coolify-redis redis-cli + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec redis redis-cli } function vite { - bash spin exec vite bash + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec vite bash } function tinker { - bash spin exec -u www-data coolify php artisan tinker + docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -u www-data coolify php artisan tinker } function default { diff --git a/tests/Feature/DevScriptFirewallDelegationTest.php b/tests/Feature/DevScriptFirewallDelegationTest.php index 3f57d6ff2c..f8c7f841a2 100644 --- a/tests/Feature/DevScriptFirewallDelegationTest.php +++ b/tests/Feature/DevScriptFirewallDelegationTest.php @@ -25,8 +25,8 @@ it('runs the coolify CLI from the development application container', function ( $script = file_get_contents(base_path('scripts/dev.sh')); expect($script)->toContain("printf '%s\\n' '/usr/local/bin/coolify'") - ->and($script)->toContain('spin exec -T coolify "$(coolify_cli_bin)" init bootstrap') - ->and($script)->toContain('spin exec -T coolify "$(coolify_cli_bin)" "$@"') + ->and($script)->toContain('docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify "$(coolify_cli_bin)" init bootstrap') + ->and($script)->toContain('docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T coolify "$(coolify_cli_bin)" "$@"') ->and($script)->toContain('ensure_coolify_container_ssh_key') ->and($script)->not->toContain('.dev/bin/coolify') ->and($script)->not->toContain('coolify-${os}-${arch}.tar.gz'); @@ -39,7 +39,7 @@ it('syncs host-resolved Lima local names into the Coolify container hosts file', ->and($script)->toContain('dscacheutil -q host -a name "$name"') ->and($script)->toContain('getent ahostsv4 "$name"') ->and($script)->toContain('sync_lima_hosts_into_coolify_container()') - ->and($script)->toContain('spin exec -T -u root coolify sh -lc') + ->and($script)->toContain('docker compose -f docker-compose.yml -f docker-compose.dev.yml exec -T -u root coolify sh -lc') ->and($script)->toContain('cat "$next" > /etc/hosts') ->and($script)->toContain('sync_lima_hosts_into_coolify_container') ->and($script)->toContain('if [ "$naked" = "true" ]; then'); @@ -58,14 +58,14 @@ it('does not require predefined UI node environment variables in the development ->and($config)->not->toContain('COOLIFY_CLI_NODES'); }); -it('supports a naked up mode that starts VMs and Spin but skips server bootstrap wiring', function () { +it('supports a naked up mode that starts VMs and Docker Compose but skips server bootstrap wiring', function () { $script = file_get_contents(base_path('scripts/dev.sh')); expect($script)->toContain('local naked=false') ->and($script)->toContain('--naked') - ->and($script)->toContain('if [ "${#spin_args[@]}" -gt 0 ]; then') - ->and($script)->toContain('spin up -d "${spin_args[@]}"') - ->and($script)->toContain('spin up -d') + ->and($script)->toContain('if [ "${#compose_args[@]}" -gt 0 ]; then') + ->and($script)->toContain('docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d "${compose_args[@]}"') + ->and($script)->toContain('docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d') ->and($script)->toContain('if [ "$naked" = "true" ]; then') ->and($script)->toContain('Skipping coolify bootstrap and Flux VM wiring') ->and($script)->toContain('coolify_bootstrap_with_retry') @@ -94,7 +94,7 @@ it('seeds bootstrapped Lima VMs into v5 development server state', function () { expect($script)->toContain('sync_v5_dev_lima_servers()') ->and($script)->toContain('COOLIFY_CLI_SSH_USER="$ssh_user"') - ->and($script)->toContain('COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" spin up -d') + ->and($script)->toContain('COOLIFY_CLI_SSH_USER="$(coolify_ssh_user)" docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d') ->and($script)->toContain('coold_vm_dns_name()') ->and($script)->toContain('$(coold_vm_dns_name "$index")') ->and($script)->toContain('v5:sync-dev-lima-servers')