diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/error/ApiErrorDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/error/ApiErrorDto.java index 4cb84a15c0747528e357329351ae53ee24fa0aea..c531bde6787e8c57096bb8fec1cc7871554b7434 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/error/ApiErrorDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/error/ApiErrorDto.java @@ -17,7 +17,7 @@ import jakarta.validation.constraints.NotNull; public class ApiErrorDto { @NotNull(message = "http status is required") - @Schema(example = "STATUS") + @Schema(example = "NOT_FOUND") private HttpStatus status; @NotNull(message = "message is required") diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java index 5b31688b8af57abc1ad0bc479a8443743a9becb9..4c77a4ac257500f57fb03c03819e6a1c0c14d858 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java @@ -146,7 +146,6 @@ public class DatabaseEndpoint { principal); final User user = userService.findByUsername(principal.getName()); final Database database = databaseService.create(createDto, principal); - messageQueueService.createUser(user.getUsername()); messageQueueService.createExchange(database, principal); queryStoreService.create(database.getId(), principal); databaseAccessRepository.save(databaseMapper.defaultCreatorAccess(database, UserUtil.getId(principal))); diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java index 88f29fa4579a29b2d8609c28503729fbe8269f35..c4d587c99ca7cb153d5ebf3617aae58d62806348 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java @@ -7,6 +7,7 @@ import at.tuwien.entities.user.User; import at.tuwien.exception.*; import at.tuwien.mapper.UserMapper; import at.tuwien.service.DatabaseService; +import at.tuwien.service.MessageQueueService; import at.tuwien.service.UserService; import at.tuwien.utils.UserUtil; import io.micrometer.core.annotation.Timed; @@ -40,13 +41,16 @@ public class UserEndpoint { private final UserMapper userMapper; private final UserService userService; private final DatabaseService databaseService; + private final MessageQueueService messageQueueService; @Autowired - public UserEndpoint(UserMapper userMapper, UserService userService, DatabaseService databaseService) { + public UserEndpoint(UserMapper userMapper, UserService userService, DatabaseService databaseService, + MessageQueueService messageQueueService) { this.userMapper = userMapper; this.userService = userService; this.databaseService = databaseService; + this.messageQueueService = messageQueueService; } @GetMapping @@ -99,14 +103,14 @@ public class UserEndpoint { }) public ResponseEntity<UserBriefDto> create(@NotNull @Valid @RequestBody SignupRequestDto data) throws RealmNotFoundException, UserAlreadyExistsException, UserEmailAlreadyExistsException, - UserNotFoundException, KeycloakRemoteException, AccessDeniedException { + UserNotFoundException, KeycloakRemoteException, AccessDeniedException, BrokerVirtualHostCreationException { log.debug("endpoint create a user, data={}", data); /* check */ userService.validateUsernameNotExists(data.getUsername()); userService.validateEmailNotExists(data.getEmail()); /* create */ - final User user = userService.create(data); - final UserBriefDto dto = userMapper.userToUserBriefDto(user); + final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data)); + messageQueueService.createUser(dto.getUsername()); log.trace("create user resulted in dto {}", dto); return ResponseEntity.status(HttpStatus.CREATED) .body(dto); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java index 1cf017ec7bf87a2acfaf600dc78bb92a90a80bcb..21b81f10e9ee1e4d095b7eba00b6ebae3d4b0470 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/endpoints/UserEndpointUnitTest.java @@ -7,6 +7,7 @@ import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.user.*; import at.tuwien.entities.user.User; import at.tuwien.exception.*; +import at.tuwien.service.MessageQueueService; import at.tuwien.service.UserService; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; @@ -40,6 +41,9 @@ public class UserEndpointUnitTest extends BaseUnitTest { @MockBean private UserService userService; + @MockBean + private MessageQueueService messageQueueService; + @Autowired private UserEndpoint userEndpoint; @@ -63,7 +67,7 @@ public class UserEndpointUnitTest extends BaseUnitTest { @WithAnonymousUser public void create_anonymous_succeeds() throws UserNotFoundException, UserEmailAlreadyExistsException, RealmNotFoundException, UserAlreadyExistsException, KeycloakRemoteException, - at.tuwien.exception.AccessDeniedException { + at.tuwien.exception.AccessDeniedException, BrokerVirtualHostCreationException { final SignupRequestDto request = SignupRequestDto.builder() .email(USER_1_EMAIL) .username(USER_1_USERNAME) @@ -300,11 +304,14 @@ public class UserEndpointUnitTest extends BaseUnitTest { protected void create_generic(SignupRequestDto data, User user) throws UserEmailAlreadyExistsException, RealmNotFoundException, UserAlreadyExistsException, UserNotFoundException, KeycloakRemoteException, - AccessDeniedException { + AccessDeniedException, BrokerVirtualHostCreationException { /* mock */ when(userService.create(data)) .thenReturn(user); + doNothing() + .when(messageQueueService) + .createUser(anyString()); /* test */ final ResponseEntity<UserBriefDto> response = userEndpoint.create(data); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java index d1e08574339d3cc4c38178a03c5a2528dc371f85..ad229d6aa39d0d6eb4e6d9c8bf8515f8dd2f571d 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceIntegrationTest.java @@ -92,7 +92,7 @@ public class UserServiceIntegrationTest extends BaseUnitTest { @Test public void create_succeeds() throws UserAlreadyExistsException, UserNotFoundException, KeycloakRemoteException, - AccessDeniedException { + AccessDeniedException, UserEmailAlreadyExistsException { final SignupRequestDto request = SignupRequestDto.builder() .username(USER_2_USERNAME) .password(USER_2_PASSWORD) @@ -113,7 +113,7 @@ public class UserServiceIntegrationTest extends BaseUnitTest { .build(); /* test */ - assertThrows(UserAlreadyExistsException.class, () -> { + assertThrows(UserEmailAlreadyExistsException.class, () -> { userService.create(request); }); } @@ -168,7 +168,7 @@ public class UserServiceIntegrationTest extends BaseUnitTest { @Test public void updatePassword_succeeds() throws KeycloakRemoteException, AccessDeniedException, UserNotFoundException, - UserAlreadyExistsException { + UserAlreadyExistsException, UserEmailAlreadyExistsException { final UserPasswordDto request = UserPasswordDto.builder() .password(USER_3_PASSWORD) .build(); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java index 1d79b4ad8611b5f276c221f599d92c44fabb9a27..35fc49b369dd59cff21217a05d54bcf8a07f7096 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/UserServiceUnitTest.java @@ -78,7 +78,7 @@ public class UserServiceUnitTest extends BaseUnitTest { @Test public void create_succeeds() throws UserNotFoundException, KeycloakRemoteException, AccessDeniedException, - UserAlreadyExistsException { + UserAlreadyExistsException, UserEmailAlreadyExistsException { /* mock */ when(userRepository.findById(USER_1_ID)) diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java index a4823fe1247e0ffc5c3acda15715e27cdd437bf6..612ee2eb372cbee0f0c10067d55eba0d2029f988 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/KeycloakGateway.java @@ -3,16 +3,13 @@ package at.tuwien.gateway; import at.tuwien.api.keycloak.UserCreateDto; import at.tuwien.api.keycloak.UserDto; import at.tuwien.api.user.UserPasswordDto; -import at.tuwien.exception.AccessDeniedException; -import at.tuwien.exception.KeycloakRemoteException; -import at.tuwien.exception.UserAlreadyExistsException; -import at.tuwien.exception.UserNotFoundException; +import at.tuwien.exception.*; import java.util.UUID; public interface KeycloakGateway { - void createUser(UserCreateDto data) throws AccessDeniedException, KeycloakRemoteException, UserAlreadyExistsException; + void createUser(UserCreateDto data) throws AccessDeniedException, KeycloakRemoteException, UserAlreadyExistsException, UserEmailAlreadyExistsException; void updateUserCredentials(UUID id, UserPasswordDto password) throws AccessDeniedException, KeycloakRemoteException; diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java index 9fb667381844506d01b7b3fdbddd27827e04d3d8..05602afae5a9879c8a03978202d8e1933f875225 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/gateway/impl/KeycloakGatewayImpl.java @@ -3,10 +3,7 @@ package at.tuwien.gateway.impl; import at.tuwien.api.keycloak.*; import at.tuwien.api.user.UserPasswordDto; import at.tuwien.config.KeycloakConfig; -import at.tuwien.exception.AccessDeniedException; -import at.tuwien.exception.KeycloakRemoteException; -import at.tuwien.exception.UserAlreadyExistsException; -import at.tuwien.exception.UserNotFoundException; +import at.tuwien.exception.*; import at.tuwien.gateway.KeycloakGateway; import at.tuwien.mapper.UserMapper; import lombok.extern.log4j.Log4j2; @@ -57,7 +54,7 @@ public class KeycloakGatewayImpl implements KeycloakGateway { @Override public void createUser(UserCreateDto data) throws AccessDeniedException, KeycloakRemoteException, - UserAlreadyExistsException { + UserAlreadyExistsException, UserEmailAlreadyExistsException { /* obtain admin token */ final HttpHeaders headers = new HttpHeaders(); headers.set("Accept", "application/json"); @@ -70,8 +67,13 @@ public class KeycloakGatewayImpl implements KeycloakGateway { log.error("Failed to create user: {}", e.getMessage()); throw new KeycloakRemoteException("Failed to create user: " + e.getMessage()); } catch (HttpClientErrorException.Conflict e) { - log.error("Conflict when creating user: {}", e.getMessage()); - throw new UserAlreadyExistsException("Conflict when creating user: " + e.getMessage()); + if (e.getMessage().contains("same email")) { + log.error("Conflict when creating user: {}", e.getMessage()); + throw new UserEmailAlreadyExistsException("Conflict when creating user: " + e.getMessage()); + } else { + log.error("Conflict when creating user: {}", e.getMessage()); + throw new UserAlreadyExistsException("Conflict when creating user: " + e.getMessage()); + } } if (!response.getStatusCode().equals(HttpStatus.CREATED)) { log.error("Failed to create user: status {} was not expected", response.getStatusCode().value()); diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java index 6a35daf1c0861e32062d84afe4a149182b528da3..3b94ad5d903eb52a0d17a5c869c2af897f205a3f 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/UserService.java @@ -43,7 +43,7 @@ public interface UserService { * @throws UserAlreadyExistsException The user already exists in the metadata database. */ User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException, - KeycloakRemoteException, UserNotFoundException; + KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException; /** * Updates the user information for a user with given id in the metadata database. diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java index deec706f9a32bbaff91a9409f82eb993f76b6cb2..d6862071b92172c548cbecf2650bb5b663ade17c 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java @@ -64,7 +64,7 @@ public class UserServiceImpl implements UserService { @Override public User create(SignupRequestDto data) throws UserAlreadyExistsException, AccessDeniedException, - KeycloakRemoteException, UserNotFoundException { + KeycloakRemoteException, UserNotFoundException, UserEmailAlreadyExistsException { /* create at authentication service */ final User entity = User.builder() .username(data.getUsername()) diff --git a/dbrepo-ui/pages/signup.vue b/dbrepo-ui/pages/signup.vue index 6cfd8b1eb6605813a343f415af015c840887aeeb..499bd33f16ce9d4096f6353ef49ce40b84f40dbf 100644 --- a/dbrepo-ui/pages/signup.vue +++ b/dbrepo-ui/pages/signup.vue @@ -8,12 +8,6 @@ <v-form ref="form" v-model="valid" @submit.prevent="submit"> <v-card flat tile> <v-card-text> - <v-alert - v-if="mailVerify" - border="left" - color="info"> - Before you can use the repository, you will need to <i>confirm</i> your email address, make sure to check your spam folder. - </v-alert> <v-row dense> <v-col sm="6"> <v-text-field @@ -108,9 +102,6 @@ export default { loadingColor () { return this.error ? 'red lighten-2' : 'primary' }, - mailVerify () { - return this.$config.mailVerify - } }, mounted () { this.loadUsers() @@ -123,7 +114,7 @@ export default { this.loading = true UserService.create(this.createAccount) .then(() => { - this.$toast.success(`Success! ${this.mailVerify ? 'Check your inbox!' : ''}`) + this.$toast.success('Success!') this.$router.push('/login') this.loading = false }) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 7eb2942561bf935e4f7998b8379e37ea83edeffa..6f85ad5ef428398878d9ed33a45ac4b0d0df2e16 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -7,6 +7,7 @@ version: "3.6" volumes: metadata-db-data: data-db-data: + auth-db-data: upload-service-data: search-db-data: broker-service-data: @@ -32,16 +33,21 @@ services: restart: "no" container_name: dbrepo-metadata-db hostname: metadata-db - image: dbrepo/metadata-db:1.3 + image: dbrepo/metadata-db:latest networks: core: volumes: - - metadata-db-data:/var/lib/mysql - - ./dbrepo-metadata-db/setup-schema_local.sql:/docker-entrypoint-initdb.d/setup-schema_local.sql + - metadata-db-data:/bitnami/mariadb + - ./setup-schema_local.sql:/docker-entrypoint-initdb.d/setup-schema_local.sql ports: - "3306:3306" env_file: - .env + healthcheck: + test: mysqladmin ping --user="$METADATA_USERNAME" --password="$METADATA_PASSWORD" --silent + interval: 10s + timeout: 5s + retries: 12 logging: driver: json-file @@ -53,11 +59,10 @@ services: networks: core: volumes: - - data-db-data:/var/lib/mysql + - data-db-data:/bitnami/mariadb - "${SHARED_FILESYSTEM}:/tmp" ports: - "3307:3306" - - "9101:9100" env_file: - .env environment: @@ -70,11 +75,37 @@ services: logging: driver: json-file + dbrepo-auth-db: + restart: "no" + container_name: dbrepo-auth-db + hostname: auth-db + image: bitnami/mariadb:10.5 + networks: + core: + volumes: + - auth-db-data:/bitnami/mariadb + ports: + - "3308:3306" + env_file: + - .env + environment: + - MARIADB_ROOT_PASSWORD=$AUTH_PASSWORD + - MARIADB_DATABASE=$AUTH_DB + healthcheck: + test: mysqladmin ping --user="$AUTH_USERNAME" --password="$AUTH_PASSWORD" --silent + interval: 10s + timeout: 5s + retries: 12 + logging: + driver: json-file + dbrepo-upload-service: restart: "no" container_name: dbrepo-upload-service hostname: upload-service image: tusproject/tusd:v1.12 + command: + - "--base-path=/api/upload/files/" networks: core: env_file: @@ -82,8 +113,6 @@ services: volumes: - upload-service-data:/data - "${SHARED_FILESYSTEM}:/srv/tusd-data/data" - ports: - - "1080:1080" logging: driver: json-file @@ -91,7 +120,7 @@ services: restart: "no" container_name: dbrepo-authentication-service hostname: authentication-service - image: dbrepo/authentication-service:1.3 + image: dbrepo/authentication-service:latest networks: core: ports: @@ -111,11 +140,13 @@ services: restart: "no" container_name: dbrepo-metadata-service hostname: metadata-service - image: dbrepo/metadata-service:1.3 + image: dbrepo/metadata-service:latest networks: core: env_file: - .env + volumes: + - "${SHARED_FILESYSTEM}:/tmp" ports: - "9099:9099" healthcheck: @@ -137,7 +168,7 @@ services: restart: "no" container_name: dbrepo-analyse-service hostname: analyse-service - image: dbrepo/analyse-service:1.3 + image: dbrepo/analyse-service:latest networks: core: ports: @@ -153,7 +184,7 @@ services: restart: "no" container_name: dbrepo-broker-service hostname: broker-service - image: dbrepo/broker-service:1.3 + image: dbrepo/broker-service:latest networks: core: ports: @@ -181,13 +212,15 @@ services: env_file: - .env healthcheck: - test: curl -s http://search-db:9200 > /dev/null || exit 1 + test: curl -s localhost:9200/_cat/indices || exit 1 + interval: 10s + timeout: 5s + retries: 12 environment: discovery.type: "single-node" ES_JAVA_OPTS: "-Xms4g -Xmx4g" logger.level: "WARN" plugins.security.disabled: "true" - bootstrap.memory_lock: "true" deploy: resources: limits: @@ -197,34 +230,11 @@ services: logging: driver: json-file - dbrepo-search-sync-agent: - restart: "no" - container_name: dbrepo-search-sync-agent - hostname: search-startup-agent - build: ./dbrepo-search-sync-agent - image: dbrepo-search-sync-agent - networks: - core: - env_file: - - .env - healthcheck: - test: wget -qO- localhost:9095/actuator/health/readiness | grep -q "UP" || exit 1 - interval: 10s - timeout: 5s - retries: 12 - depends_on: - dbrepo-metadata-db: - condition: service_healthy - dbrepo-search-db: - condition: service_healthy - logging: - driver: json-file - dbrepo-ui: restart: "no" container_name: dbrepo-ui hostname: ui - image: dbrepo/ui:1.3 + image: dbrepo/ui:latest networks: core: public: diff --git a/docker-compose.yml b/docker-compose.yml index 919e615a8fee777fd1ef2df444d5c6713fea1584..e99659865465b2b4382dc6e9734d5a88f8a60e83 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -82,7 +82,7 @@ services: restart: "no" container_name: dbrepo-auth-db hostname: auth-db - image: mariadb:10.5 + image: bitnami/mariadb:10.5 networks: core: volumes: @@ -240,31 +240,6 @@ services: logging: driver: json-file -# dbrepo-search-sync-agent: -# restart: "no" -# container_name: dbrepo-search-sync-agent -# hostname: search-startup-agent -# build: ./dbrepo-search-sync-agent -# image: dbrepo-search-sync-agent -# networks: -# core: -# env_file: -# - .env -# healthcheck: -# test: wget -qO- localhost:9050/actuator/health/readiness | grep -q "UP" || exit 1 -# interval: 10s -# timeout: 5s -# retries: 12 -# depends_on: -# dbrepo-metadata-db: -# condition: service_healthy -# dbrepo-search-db: -# condition: service_started -# dbrepo-authentication-service: -# condition: service_healthy -# logging: -# driver: json-file - dbrepo-ui: restart: "no" container_name: dbrepo-ui diff --git a/install.sh b/install.sh index 627a55974e8db2ca4808936f54a9f54b49564824..0e57e31a8dd50cd4789a50fa07e2324ee36434d1 100644 --- a/install.sh +++ b/install.sh @@ -1,10 +1,12 @@ #!/bin/bash -if [ `whoami` -neq "root" ]; then +# dependency +if [ "$USER" != "root" ]; then echo "This script needs sudo privileges!" exit 1 fi +# dependency docker info > /dev/null if [ $? -ne 0 ]; then echo "Docker is not installed (or accessible in bash) on your system:" @@ -14,27 +16,31 @@ if [ $? -ne 0 ]; then exit 2 fi -echo "Gathering environment ..." +# environment +echo "[🚀] Gathering environment ..." curl -sSL -o .env https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/.env.unix.example curl -sSL -o docker-compose.yml https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/docker-compose.prod.yml -curl -sSL -o dbrepo.conf https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/master/dbrepo.conf +curl -sSL -o dbrepo.conf https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-gateway-service/dbrepo.conf curl -sSL -o setup-schema_local.sql https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/raw/dev/dbrepo-metadata-db/setup-schema_local.sql -echo "Pulling images ..." +echo "[📦] Pulling images ..." docker compose pull MAX_MAP_COUNT=$(cat /proc/sys/vm/max_map_count) if [ "$MAX_MAP_COUNT" -lt 262144 ]; then - echo "Preparing environment ..." + echo "[🚀] Preparing environment ..." echo "vm.max_map_count=262144" >> /etc/sysctl.conf sysctl -p fi -echo "Starting DBRepo ..." +echo "[✨] Starting DBRepo ..." docker compose up -d if [ $? -eq 0 ]; then - echo "Successfully started. You can now inspect the logs with:" + echo "[🎉] Successfully started!" echo "" - echo "docker compose logs -f" -fi \ No newline at end of file + echo "You can now inspect the logs with:" + echo "" + echo " docker compose logs -f" + echo "" +fi