diff --git a/README.md b/README.md index be732373f7..157510b19f 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Once installed, you can start a production deployment1 with a single ```sh # Automatically sets up an external access URL on *.try.coder.app -coder server --tunnel +coder server # Requires a PostgreSQL instance and external access URL coder server --postgres-url --access-url diff --git a/cli/resetpassword_test.go b/cli/resetpassword_test.go index 8521a28e16..1beade14e9 100644 --- a/cli/resetpassword_test.go +++ b/cli/resetpassword_test.go @@ -41,6 +41,7 @@ func TestResetPassword(t *testing.T) { serverCmd, cfg := clitest.New(t, "server", "--address", ":0", + "--access-url", "example.com", "--postgres-url", connectionURL, "--cache-dir", t.TempDir(), ) diff --git a/cli/server.go b/cli/server.go index 7fbef723a4..1d54f8936a 100644 --- a/cli/server.go +++ b/cli/server.go @@ -111,7 +111,6 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) tlsEnable bool tlsKeyFiles []string tlsMinVersion string - tunnel bool traceEnable bool secureAuthCookie bool sshKeygenAlgorithmRaw string @@ -243,26 +242,23 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) if tlsEnable { localURL.Scheme = "https" } - if accessURL == "" { - accessURL = localURL.String() - } var ( ctxTunnel, closeTunnel = context.WithCancel(ctx) - devTunnel *devtunnel.Tunnel - devTunnelErr <-chan error + tunnel *devtunnel.Tunnel + tunnelErr <-chan error ) defer closeTunnel() - // If we're attempting to tunnel in dev-mode, the access URL - // needs to be changed to use the tunnel. - if tunnel { - cmd.Printf("Opening tunnel so workspaces can connect to your deployment\n") - devTunnel, devTunnelErr, err = devtunnel.New(ctxTunnel, logger.Named("devtunnel")) + // If the access URL is empty, we attempt to run a reverse-proxy tunnel + // to make the initial setup really simple. + if accessURL == "" { + cmd.Printf("Opening tunnel so workspaces can connect to your deployment. For production scenarios, specify an external access URL\n") + tunnel, tunnelErr, err = devtunnel.New(ctxTunnel, logger.Named("devtunnel")) if err != nil { return xerrors.Errorf("create tunnel: %w", err) } - accessURL = devTunnel.URL + accessURL = tunnel.URL } accessURLParsed, err := parseURL(ctx, accessURL) @@ -288,11 +284,11 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) if isLocal { reason = "isn't externally reachable" } - cmd.Printf("%s The access URL %s %s, this may cause unexpected problems when creating workspaces. Generate a unique *.try.coder.app URL with:\n", cliui.Styles.Warn.Render("Warning:"), cliui.Styles.Field.Render(accessURLParsed.String()), reason) - cmd.Println(cliui.Styles.Code.Render(strings.Join(os.Args, " ") + " --tunnel")) + cmd.Printf("%s The access URL %s %s, this may cause unexpected problems when creating workspaces. Generate a unique *.try.coder.app URL by not specifying an access URL.\n", cliui.Styles.Warn.Render("Warning:"), cliui.Styles.Field.Render(accessURLParsed.String()), reason) } - cmd.Printf("View the Web UI: %s\n", accessURLParsed.String()) + // A newline is added before for visibility in terminal output. + cmd.Printf("\nView the Web UI: %s\n", accessURLParsed.String()) // Used for zero-trust instance identity with Google Cloud. googleTokenValidator, err := idtoken.NewValidator(ctx, option.WithoutAuthentication()) @@ -472,7 +468,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) OIDCIssuerURL: oidcIssuerURL, Prometheus: promEnabled, STUN: len(derpServerSTUNAddrs) != 0, - Tunnel: tunnel, + Tunnel: tunnel != nil, }) if err != nil { return xerrors.Errorf("create telemetry reporter: %w", err) @@ -569,17 +565,17 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) eg.Go(func() error { // Make sure to close the tunnel listener if we exit so the // errgroup doesn't wait forever! - if tunnel { - defer devTunnel.Listener.Close() + if tunnel != nil { + defer tunnel.Listener.Close() } return server.Serve(listener) }) - if tunnel { + if tunnel != nil { eg.Go(func() error { defer listener.Close() - return server.Serve(devTunnel.Listener) + return server.Serve(tunnel.Listener) }) } go func() { @@ -624,7 +620,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) _, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Bold.Render( "Interrupt caught, gracefully exiting. Use ctrl+\\ to force quit", )) - case exitErr = <-devTunnelErr: + case exitErr = <-tunnelErr: if exitErr == nil { exitErr = xerrors.New("dev tunnel closed unexpectedly") } @@ -650,9 +646,9 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) // in-flight requests, give in-flight requests 5 seconds to // complete. cmd.Println("Shutting down API server...") - err = shutdownWithTimeout(server.Shutdown, 5*time.Second) + err = shutdownWithTimeout(server.Shutdown, 3*time.Second) if err != nil { - cmd.Printf("API server shutdown took longer than 5s: %s", err) + cmd.Printf("API server shutdown took longer than 3s: %s\n", err) } else { cmd.Printf("Gracefully shut down API server\n") } @@ -694,10 +690,10 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) cmd.Println("Done waiting for WebSocket connections") // Close tunnel after we no longer have in-flight connections. - if tunnel { + if tunnel != nil { cmd.Println("Waiting for tunnel to close...") closeTunnel() - <-devTunnelErr + <-tunnelErr cmd.Println("Done waiting for tunnel") } @@ -855,8 +851,6 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) "Paths to the private keys for each of the certificates. It requires a PEM-encoded file") cliflag.StringVarP(root.Flags(), &tlsMinVersion, "tls-min-version", "", "CODER_TLS_MIN_VERSION", "tls12", `Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`) - cliflag.BoolVarP(root.Flags(), &tunnel, "tunnel", "", "CODER_TUNNEL", false, - "Workspaces must be able to reach the `access-url`. This overrides your access URL with a public access URL that tunnels your Coder deployment.") cliflag.BoolVarP(root.Flags(), &traceEnable, "trace", "", "CODER_TRACE", false, "Whether application tracing data is collected.") cliflag.BoolVarP(root.Flags(), &secureAuthCookie, "secure-auth-cookie", "", "CODER_SECURE_AUTH_COOKIE", false, diff --git a/cli/server_test.go b/cli/server_test.go index 6f4192f42c..fe71da9309 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -56,6 +56,7 @@ func TestServer(t *testing.T) { root, cfg := clitest.New(t, "server", "--address", ":0", + "--access-url", "example.com", "--postgres-url", connectionURL, "--cache-dir", t.TempDir(), ) @@ -87,6 +88,7 @@ func TestServer(t *testing.T) { root, cfg := clitest.New(t, "server", "--address", ":0", + "--access-url", "example.com", "--cache-dir", t.TempDir(), ) pty := ptytest.New(t) @@ -159,6 +161,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--access-url", "foobarbaz.mydomain", "--cache-dir", t.TempDir(), ) @@ -189,6 +192,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--access-url", "https://google.com", "--cache-dir", t.TempDir(), ) @@ -218,6 +222,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--tls-enable", "--tls-min-version", "tls9", "--cache-dir", t.TempDir(), @@ -234,6 +239,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--tls-enable", "--tls-client-auth", "something", "--cache-dir", t.TempDir(), @@ -290,6 +296,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--cache-dir", t.TempDir(), } args = append(args, c.args...) @@ -310,6 +317,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--tls-enable", "--tls-cert-file", certPath, "--tls-key-file", keyPath, @@ -349,6 +357,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--tls-enable", "--tls-cert-file", cert1Path, "--tls-key-file", key1Path, @@ -432,6 +441,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--provisioner-daemons", "1", "--cache-dir", t.TempDir(), ) @@ -458,6 +468,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--trace=true", "--cache-dir", t.TempDir(), ) @@ -495,6 +506,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--telemetry", "--telemetry-url", server.URL, "--cache-dir", t.TempDir(), @@ -525,6 +537,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--provisioner-daemons", "1", "--prometheus-enable", "--prometheus-address", ":"+strconv.Itoa(randomPort), @@ -577,6 +590,7 @@ func TestServer(t *testing.T) { "server", "--in-memory", "--address", ":0", + "--access-url", "example.com", "--oauth2-github-client-id", "fake", "--oauth2-github-client-secret", "fake", "--oauth2-github-enterprise-base-url", fakeRedirect, diff --git a/coder.env b/coder.env index c7c880eb57..0c198649e0 100644 --- a/coder.env +++ b/coder.env @@ -1,11 +1,4 @@ -# Coder must be reachable from an external URL -# for users and workspaces to connect. - -# Option 1) Enable CODER_TUNNEL to generate a -# unique *. try.coder.com access URL -CODER_TUNNEL=false - -# Option 2) Set an access URL +# Coder must be reachable from an external URL for users and workspaces to connect. # e.g. https://coder.example.com CODER_ACCESS_URL= diff --git a/coderd/authorize.go b/coderd/authorize.go index c0b8eaba75..b23acbc2ba 100644 --- a/coderd/authorize.go +++ b/coderd/authorize.go @@ -119,7 +119,7 @@ func (api *API) checkAuthorization(rw http.ResponseWriter, r *http.Request) { return } - api.Logger.Warn(ctx, "check-auth", + api.Logger.Debug(ctx, "check-auth", slog.F("my_id", httpmw.APIKey(r).UserID), slog.F("got_id", auth.ID), slog.F("name", auth.Username), diff --git a/coderd/csp.go b/coderd/csp.go index 473cf6fd60..3971946380 100644 --- a/coderd/csp.go +++ b/coderd/csp.go @@ -34,7 +34,7 @@ func (api *API) logReportCSPViolations(rw http.ResponseWriter, r *http.Request) for k, v := range v.Report { fields = append(fields, slog.F(k, v)) } - api.Logger.Warn(ctx, "csp violation", fields...) + api.Logger.Debug(ctx, "csp violation", fields...) httpapi.Write(ctx, rw, http.StatusOK, "ok") } diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index f7301b9bd3..41d39938d9 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -311,7 +311,7 @@ func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (* conn, err := tailnet.NewConn(&tailnet.Options{ Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(), 128)}, DERPMap: derpMap, - Logger: api.Logger.Named("tailnet").Leveled(slog.LevelDebug), + Logger: api.Logger.Named("tailnet"), }) if err != nil { return nil, xerrors.Errorf("create tailnet conn: %w", err) @@ -453,7 +453,7 @@ func (api *API) workspaceAgentCoordinate(rw http.ResponseWriter, r *http.Request // Ignore all trace spans after this. ctx = trace.ContextWithSpan(ctx, tracing.NoopSpan) - api.Logger.Info(ctx, "accepting agent", slog.F("resource", resource), slog.F("agent", workspaceAgent)) + api.Logger.Info(ctx, "accepting agent", slog.F("agent", workspaceAgent)) defer conn.Close(websocket.StatusNormalClosure, "") diff --git a/docker-compose.yaml b/docker-compose.yaml index 0c6e169500..a8bab5a977 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,9 +13,6 @@ services: # that workspaces can reach. This cannot be localhost # or 127.0.0.1 for non-Docker templates! CODER_ACCESS_URL: "${CODER_ACCESS_URL}" - # Alternatively, you can enable CODER_TUNNEL for - # proof-of-concept deployments. - CODER_TUNNEL: "${CODER_TUNNEL:-false}" # If the coder user does not have write permissions on # the docker socket, you can uncomment the following # lines and set the group ID to one that has write diff --git a/docs/admin/configure.md b/docs/admin/configure.md index 63c6a44930..8e70475fe2 100644 --- a/docs/admin/configure.md +++ b/docs/admin/configure.md @@ -1,11 +1,6 @@ Coder server's primary configuration is done via environment variables. For a full list of the options, run `coder server --help` on the host. -## Tunnel - -For proof-of-concept deployments, you can set `CODER_TUNNEL=true` to run Coder on a unique `*.try.coder.app` URL. -This is a quick way to allow users and workspaces outside your LAN to connect to Coder. - ## Access URL `CODER_ACCESS_URL` is required if you are not using the tunnel. Set this to the external URL @@ -14,6 +9,11 @@ should not be localhost. > Access URL should be a external IP address or domain with DNS records pointing to Coder. +### Tunnel + +If an access URL is not specified, Coder will create +a publicly accessible URL to reverse proxy your deployment for simple setup. + ## Wildcard access URL `CODER_WILDCARD_ACCESS_URL` is necessary for [port forwarding](../networking/port-forwarding.md#dashboard) diff --git a/docs/images/quickstart/aws/aws7.png b/docs/images/quickstart/aws/aws7.png deleted file mode 100644 index 3d7b08f3da..0000000000 Binary files a/docs/images/quickstart/aws/aws7.png and /dev/null differ diff --git a/docs/images/quickstart/azure/azure7.png b/docs/images/quickstart/azure/azure7.png deleted file mode 100644 index 3d7b08f3da..0000000000 Binary files a/docs/images/quickstart/azure/azure7.png and /dev/null differ diff --git a/docs/install/binary.md b/docs/install/binary.md index fe360f1b0c..bde79b0422 100644 --- a/docs/install/binary.md +++ b/docs/install/binary.md @@ -15,7 +15,7 @@ Coder publishes self-contained .zip and .tar.gz archives in [GitHub releases](ht ```sh # Automatically sets up an external access URL on *.try.coder.app - coder server --tunnel + coder server # Requires a PostgreSQL instance and external access URL coder server --postgres-url --access-url diff --git a/docs/install/docker.md b/docs/install/docker.md index 13f0eb7437..565bdd2f59 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -4,7 +4,7 @@ You can install and run Coder using the official Docker images published on [Git Docker is required. See the [official installation documentation](https://docs.docker.com/install/). -## Run Coder with built-in database and tunnel (quick) +## Run Coder with the built-in database (quick) For proof-of-concept deployments, you can run a complete Coder instance with the following command: @@ -14,7 +14,6 @@ export CODER_DATA=$HOME/.config/coderv2-docker export DOCKER_GROUP=$(getent group docker | cut -d: -f3) mkdir -p $CODER_DATA docker run --rm -it \ - -e CODER_TUNNEL=true \ -v $CODER_DATA:/home/coder/.config \ -v /var/run/docker.sock:/var/run/docker.sock \ --group-add $DOCKER_GROUP \ @@ -68,7 +67,7 @@ an PostgreSQL container and volume. ```sh cd coder - CODER_TUNNEL=true docker-compose up + docker-compose up ``` For production deployments, we recommend setting an [access URL](../admin/configure.md#access-url): @@ -79,8 +78,6 @@ an PostgreSQL container and volume. CODER_ACCESS_URL=https://coder.example.com docker-compose up ``` - > Without `CODER_ACCESS_URL` or `CODER_TUNNEL` set, Coder will bind to `localhost:7080`. This will only work for Docker-based templates. - 4. Visit the web ui via the configured url. You can add `/login` to the base url to create the first user via the ui. 5. Follow the on-screen instructions log in and create your first template and workspace diff --git a/docs/install/packages.md b/docs/install/packages.md index d8e455411d..13a96e0b30 100644 --- a/docs/install/packages.md +++ b/docs/install/packages.md @@ -7,7 +7,7 @@ 1. Run Coder as a system service. ```sh - # Set up an access URL or enable CODER_TUNNEL + # Optional) Set up an access URL sudo vim /etc/coder.d/coder.env # To systemd to start Coder now and on reboot diff --git a/docs/quickstart.md b/docs/quickstart.md index ed59929380..98067a6361 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -12,8 +12,6 @@ Please [install Coder](../install) before proceeding with the steps below. 1. Run `coder login ` in a new terminal and follow the interactive instructions to create your owner user and password. -> If using `coder server --tunnel`, the Access URL appears in the terminal logs. - ## Templates To get started using templates, run the following command to generate a sample template: diff --git a/docs/quickstart/aws.md b/docs/quickstart/aws.md index 13a5bb8498..95e382fa5e 100644 --- a/docs/quickstart/aws.md +++ b/docs/quickstart/aws.md @@ -78,15 +78,7 @@ curl -fsSL https://coder.com/install.sh | sh ## Run Coder -First, edit the `coder.env` file to enable `CODER_TUNNEL` by setting the value to true with the following command: - -```sh -sudo vim /etc/coder.d/coder.env -``` - - - -Exit vim and run the following command to start Coder as a system level service: +Run the following command to start Coder as a system level service: ```sh sudo systemctl enable --now coder diff --git a/docs/quickstart/azure.md b/docs/quickstart/azure.md index 0b77406cf3..26e63ae8fd 100644 --- a/docs/quickstart/azure.md +++ b/docs/quickstart/azure.md @@ -49,15 +49,7 @@ curl -fsSL | sh ## Run Coder -First, edit the `coder.env` file to enable `CODER_TUNNEL` by setting the value to true with the following command: - -```sh -sudo vim /etc/coder.d/coder.env -``` - - - -Exit vim and run the following command to start Coder as a system level service: +Run the following command to start Coder as a system level service: ```sh sudo systemctl enable --now coder diff --git a/docs/quickstart/docker.md b/docs/quickstart/docker.md index 3f17877a2c..da19b4f3be 100644 --- a/docs/quickstart/docker.md +++ b/docs/quickstart/docker.md @@ -15,19 +15,13 @@ Coder with Docker has the following advantages: 1. [Install and launch Coder](../install) - Next, we export the `CODER_ADDRESS` and `CODER_ACCESS_URL` environment - variables. We can use localhost for the Access URL since the workspaces - all run on the same machine. `CODER_ADDRESS` is where coder server binds - while `CODER_ACCESS_URL` is where it's accessed. We use `:7080` to bind - to all interfaces. + The Coder server binds to port 3000 by default. Use `--address :` to customize it! ```bash - $ export CODER_ADDRESS=:7080 - $ export CODER_ACCESS_URL=http://localhost:7080 - $ coder server --address $CODER_ADDRESS --access-url $CODER_ACCESS_URL + $ coder server ``` -1. Run `coder login http://localhost:7080` in a new terminal and follow the +1. Run `coder login http://localhost:3000` in a new terminal and follow the interactive instructions to create your user. 1. Pull the "Docker" example template using the interactive `coder templates init`: @@ -38,7 +32,7 @@ Coder with Docker has the following advantages: ``` 1. Push up the template with `coder templates create` -1. Open the dashboard in your browser (http://localhost:7080) to create your +1. Open the dashboard in your browser (http://localhost:3000) to create your first workspace: diff --git a/install.sh b/install.sh index 9e0d7b0e74..bbecb4d598 100755 --- a/install.sh +++ b/install.sh @@ -121,7 +121,7 @@ $1 package has been installed. To run Coder as a system service: - # Set up an external access URL or enable CODER_TUNNEL + # Optional) Set up an external access URL $ sudo vim /etc/coder.d/coder.env # Use systemd to start Coder now and on reboot $ sudo systemctl enable --now coder diff --git a/scripts/develop.sh b/scripts/develop.sh index 0e001fcb66..a1ab8a884c 100755 --- a/scripts/develop.sh +++ b/scripts/develop.sh @@ -59,7 +59,7 @@ CODER_DEV_SHIM="${PROJECT_ROOT}/scripts/coder-dev.sh" # rather than leaving things in an inconsistent state. trap 'kill -TERM -$$' ERR cdroot - "${CODER_DEV_SHIM}" server --address 0.0.0.0:3000 --tunnel || kill -INT -$$ & + "${CODER_DEV_SHIM}" server --address 0.0.0.0:3000 || kill -INT -$$ & echo '== Waiting for Coder to become ready' timeout 60s bash -c 'until curl -s --fail http://localhost:3000 > /dev/null 2>&1; do sleep 0.5; done' diff --git a/site/e2e/playwright.config.ts b/site/e2e/playwright.config.ts index 5d7ef08ea9..e39c412640 100644 --- a/site/e2e/playwright.config.ts +++ b/site/e2e/playwright.config.ts @@ -24,7 +24,7 @@ const config: PlaywrightTestConfig = { command: `go run -tags embed ${path.join( __dirname, "../../enterprise/cmd/coder/main.go", - )} server --in-memory`, + )} server --in-memory --access-url 127.0.0.1:${basePort}`, port: basePort, timeout: 120 * 10000, reuseExistingServer: false,