데브코스

[16주차 - DAY4] 도서 정보 사이트 - 모바일 대응, 도커

미안하다 강림이 좀 늦었다 2024. 6. 12. 17:02

 

 

모바일 대응

이 글에서는 작성하지 않았지만 배너, footer, 메인 페이지의 리뷰 등의 컴포넌트도 모바일 대응으로 수정했다.

style/theme.ts

모바일, 태블릿, 데스크탑의 width를 정의한다.

export type MediaQuery = 'mobile' | 'tablet' | 'desktop';

interface Theme {
    ...
    mediaQuery: {
        [key in MediaQuery]: string;
    };
}

export const light: Theme = {
    ...
    mediaQuery: {
        mobile: '(max-width: 768px)',
        tablet: '(max-width: 1024px)',
        desktop: '(min-width: 1025px)'
    }
};

 

hooks/useMediaQuery.ts

현재 화면 크기가 모바일인지에 대해 확인하는 훅을 작성한다.

import { getTheme } from "@/style/theme";
import { useEffect, useState } from "react"

export const useMediaQuery = () => {
    const [isMobile, setIsMobile] = useState(
        window.matchMedia(getTheme('light').mediaQuery.mobile).matches
    );

    useEffect(() => {
        const isMobileQuery = window.matchMedia(getTheme('light').mediaQuery.mobile).matches;

        setIsMobile(isMobileQuery);
    }, []);

    return { isMobile };
}

 

components/common/Header.tsx

isMobileOpen은 카테고리 선택창의 표시 여부를 나타낸다. 메뉴 버튼을 누르면 해당 변수가 true로 설정된다. HeaderStyle에 Props로 isMobileOpen을 념겨줘서 카테고리 선택창 표시를 결정한다.

 

모바일 너비일 경우에 대한 스타일 설정은 @media screen AND ${({ theme }) => theme.mediaQuery.mobile} 안에 작성한다.

function Header() {
    ...
    const [isMobileOpen, setIsMobileOpen] = useState(false);


    return (
        <HeaderStyle $isOpen={isMobileOpen}>
            ...
            <nav className="category">
                <button
                    className="menu-button"
                    onClick={() => setIsMobileOpen(!isMobileOpen)}
                >
                    {isMobileOpen ? <FaAngleRight /> : <FaBars />}
                </button>
                ...
            </nav>
            <nav className="auth">
                ...
            </nav >
        </HeaderStyle >
    );
}

interface HeaderStyleProps {
    $isOpen: boolean;
}

const HeaderStyle = styled.header<HeaderStyleProps>`
    ...

    @media screen AND ${({ theme }) => theme.mediaQuery.mobile} {
        ...
    }
`;

 

components/main/MainBest.tsx

모바일인 경우 한 행에 도서를 2개씩 보여주도록 설정한다. 신간 부분도 동일하게 작성한다.

const MainBestStyle = styled.div`
    ...

    @media screen AND ${({ theme }) => theme.mediaQuery.mobile} {
        grid-template-columns: repeat(2, 1fr);
    }
`;

 

pages/Login.tsx

input에 inputMode 속성을 준다. PC로 확인했을 때는 차이를 못느끼지만 모바일로 확인해 보면 inputMode에 따라 설정되는 키패드가 다르다. email로 설정하면 '@'가 있는 키패드가 나타난다.

<InputText
	placeholder="이메일"
	inputType="email"
	{...register('email', { required: true })}
	inputMode="email"
/>

 

 

도커

이미지와 컨테이너

  • 이미지: 응용을 실행하는 데 필요한 모든 파일들과 그것을 실행하는 방법을 묶어 놓은 것이다. 상태 정보를 가지고 있지 않다.
  • 컨테이너: 이미지 실행의 인스턴스로 실행 상태를 유지한다.

 

명령어

명령어 설명
docker ps -a 현재 실행 중인 컨테이너들의 정보를 조회한다.
a 옵션을 붙이면 중단되어있는 것까지 포함한다.
docker run <이미지이름> 이미지를 로컬 또는 레지스트리에서 가져와서 컨테이너를 만들어 실행한다.
docker images 로컬 컴퓨터에 가지고 있는 이미지들의 정보를 조회한다.
docker stop <컨테이너이름 또는 아이디> 현재 실행 중인 컨테이너를 중단한다. 컨테이너가 없어지지는 않는다.
docker rm <컨테이너 이름 또는 아이디> 컨테이너를 삭제한다.
docker rmi <이미지 이름 또는 아이디> 이미지를 삭제한다.

 

이미지 다운로드

아래 명령을 실행하면 httpd 이미지를 다운받는다.

docker pull httpd

 

컨테이너 실행

아래 명령은 nginx 이미지 파일로 컨테이너를 실행하라는 의미이다.

rm은 이 컨테이너가 실행을 마치면 자동으로 삭제되도록 하는 옵션이고,

d 옵션은 detached mode로 백그라운드 모드를 의미한다,

p 옵션으로 포트를 설정하는데, [호스트 포트]:[컨테이너 포트]로 지정한다. 이걸 설정해야 브라우저에서 localhost로 접속할 수 있다.

name 옵션으로 컨테이너의 이름을 지정한다.

해당 이미지 파일이 다운받아져있지 않으면 자동으로 다운받아진다.

docker run --rm -d -p 8080:80 --name my_nginx nginx:latest

 

이미지 생성

1. Dockerfile을 다음과 같이 작성한다.

FROM httpd:latest

RUN echo "<html><body><h1>Docker build test</h1></body></html>" > /usr/local/apache2/htdocs/index.html

ENTRYPOINT /usr/local/bin/httpd-foreground

 

2. 방금 만든 파일이 있는 폴더 안에서 다음 명령을 실행한다.

docker build -t my_httpd:0.2 .

 

3. 이미지가 만들어졌는지 확인한다.

 

4. docker hub에 로그인한다.

docker login

 

5. 만들었던 이미지의 레포지토리 이름을 변경한다. 이때 반드시 도커 계정의 사용자 이름을 적어야 한다.

docker tag my_httpd:0.2 ncherryu/my_httpd:0.2

 

6. push 한다.

docker push ncherryu/my_httpd:0.2

 

7. docker hub의 내 레포지토리에 가보면 생성한 이미지를 확인할 수 있다.

컨테이너에 환경 변수 전달

1. Dockerfile을 다음과 같이 작성한다. ENV NAME에 적힌 값이 환경 변수이다.

FROM ubuntu:22.04

ENV NAME Grepp

RUN apt-get update && apt-get install -y python3 
COPY hello.py .

ENTRYPOINT ["python3", "hello.py"]

 

2. hello.py를 다음과 같이 작성한다.

import os
print("Hello World from %s" % os.environ["NAME"])

 

3. 이미지를 만든다.

docker build -t hello:0.2 .

 

4-1. 컨테이너를 실행하면 환경 변수로 설정한 이름이 나오는 것을 확인할 수 있다.

 

4-2. e 옵션으로도 환경 변수를 설정할 수 있다.

 

volume으로 host와 container 폴더 공유

1. 호스트의 해당 경로에 A.txt 파일을 생성한다.

 

2. v 옵션으로 볼륨을 설정한다. [1의 폴더 경로]:[컨테이너 폴더]를 입력하고, 쉘을 실행한다.

docker run -it -v C:/Users/김민진/work/vol:/host_directory ubuntu:22.04 /bin/bash

 

3. 2에서 입력한 컨테이너 폴더에 A.txt. 파일이 있는 것을 확인할 수 있다.

 

4. 컨테이너에서 B.txt. 파일을 만든다.

 

5. 호스트에서도 B.txt를 확인할 수 있다.

 

volume 생성

다음 명령어로 볼륨을 생성할 수 있다.

docker volume create 볼륨이름

 

아래 명령어로 볼륨 목록을 확인한다.

docker volume ls

 

다음 명령으로 볼륨의 상세 정보를 볼 수 있다.

docker inspect 볼륨이름

 

 

배운 점

  • 도커 이미지와 컨테이너를 생성하는 방법을 배웠다.
  • Dockerfile 안에서 ENV로 환경 변수를 설정하거나 컨테이너를 실행할 때 e 옵션으로 환경 변수를 설정할 수 있다.
  • volume을 사용하면 호스트와 컨테이너가 폴더를 공유할 수 있다.