카페24 호스팅의 PHP 버전 올리기

내 블로그는 2013년도부터 카페24의 호스팅 서비스를 이용하고 있다. 작년 말 부턴가 내 호스팅 서버의 PHP 버전이 낮아 워드프레스를 최신버전으로 업데이트 할 수 없었다. 하나하나 알아서 하기는 귀찮아 참고할만한 경험기를 인터넷에서 찾으려 했으나 찾지 못했다. 업그레이드도 차일피일 미루고 있었다. 얼마 전 부터 이미지 최적화 플러그인까지 업데이트 지원이 중단되자 결국 혼자서 진행했다. 그 과정을 미래의 나를 위해 정리해 둔다.

아래의 작업은 카페24 메인 > 우측 상단의 ‘나의 서비스 관리‘ 페이지에서 이루어 진다.

사전 작업 하기

참고로, 카페24 사이트에서는 서버에 저장된 파일들(이미지, 워드프레스 PHP 코드 등)을 데이터로, 데이터 베이스 서버에 저장된 자료를 DB라고 부른다.

  1. 데이터/DB 백업
    ‘계정관리’ 메뉴 > ‘백업받기/올리기’ 메뉴에서 내 자료를 백업할 수 있다. 둘 다, 수 분 정도 걸리니 먼저 걸어두자.
  2. (필요하다면) FTP 접속 준비
    ‘보안관리’ 메뉴 > ‘FTP/Shell 접속설정’ 메뉴에서 FTP 접속을 위한 준비를 할 수 있다. FTP 접속 제한 설정이나 세션 리셋 기능 등이 있다. FTP 접속방법은 카페24 웹 FTP나 FileZilla 프로그램 사용을 제안하는데, 나는 FileZilla를 설치했다.
  3. (잊어버렸다면) FTP 비밀번호 변경하기
    카페24 사이트의 로그인 정보와 별도로 데이터가 저장된 내 서버와 DB에 접근하는 비번이 따로 있다. ‘서비스 접속관리’ 메뉴 > ‘FTP 비밀번호 변경’에서 변경하자.
  4. 서버에 접속하기
    앞에서 설치한 FileZilla를 이용해 내 서버에 접속하자. 참고로, 카페24에서 여기에 그림에 설명을 곁들여 자세히 설명하고 있다.
  5. 데이터/DB 받기
    내 서버에 접속하면, 데이터/DB 백업 시 안내된 위치에 데이터와 DB 파일이 있을 것이다. 이를 내 PC(로컬, 현재 작업 중인 컴퓨터)로 다운받자.

이 것으로 작업을 할 준비를 마쳤다.

카페24에서 하루 1회(매일 새벽) 데이터/DB를 자동 백업하고, ‘계정관리’ 메뉴 > ‘DATA&DB 복원/백업’ 메뉴를 통해 복원 기능을 제공하고 있다. 하지만, 이번처럼 PHP 버전을 변경하고 나서 변경 전 자료를 이용해 자동 복원이 시도하니 계속 실패했다. 그러니, 번거롭지만 꼭 사전 작업을 통해 자료를 백업하자.

본 작업하기

  1. PHP 버전 업그레이드
    ‘연장/변경/추가옵션’ 메뉴 > ‘변경신청’ 메뉴에서 PHP 버전을 변경할 수 있다. 상단의 ‘사용중인 서비스 정보’ 부분에 내 정보가 나오고 하단의 ‘서버 환경 변경’ 부분에서 변경할 PHP 버전을 고를 수 있다.
    본인이 변경하고자 하는 PHP 버전을 고른 후 가운데 하단의 ‘변경 신청’ 버튼을 누르면 바로 변경이 시작된다.
  2. 변경완료 될 때까지 대기
    카페24는 30분 정도 대기를 권장한다. 하지만, 서버 설정 변경 완료 안내 기능이 없어 넉넉하게 40~50분정도 기다린 것 같다.
  3. DB 복구하기
    DB 백업을 받았던 ‘계정관리’ 메뉴 > ‘백업받기/올리기’ 메뉴에 가면 DB 복구를 할 수 있다.  카페24 사이트의 가이드대로 FileZilla를 이용해 DB 백업 파일을 업로드하여, DB를 복구한다.
  4. 데이터 복구하기
    앞서 받아놓은 압축된 .tar.gz 파일을 압축해제한 후, 처음과 동일한 경로로 FileZilla를 통해 파일을 호스팅 서버에 올린다.
  5. 정상동작 확인하기
    운이 좋다면.. 워드프레스가 바로 동작할 수도 있다.

이 것으로 본 작업을 마쳤다.

개인적으로 데이터보다는 DB 복구를 먼저하길 권장한다. 데이터 복구보다 DB 복구가 훨씬 쉽고, 데이터 복구를 먼저하면 웹 사이트가 동작하지 않는 원인이 데이터 때문인지 DB 때문인지 헷갈릴 수 있기 때문이다.

내 호스팅의 경우, UTF-8 + PHP 5.3 + MySQL 5.x 조합인 서버 구성을 UTF-8 + PHP 7.x + MariaDB 10.0.x 구성으로 변경했다. PHP 7.x 이상 버전에서는 UTF-8 언어셋과 MariaDB를 강제로 쓰도록 제약하는 것 같다. 참고로, MariaDB는 MySQL에서 포크된 프로젝트이므로 사용자 입장에서는 차이가 없으니 염려말자.

사후 작업하기

  1. 워드프레스 업데이트 하기
    워드프레스 업데이트가 안된다면 기존에 설치된 플러그인, 테마를 모두 제거한 후 업데이트 해보자. 테마와 플러그인은 워드프레스 업데이트 후 다시 설치하면 되니 아까워 말자. 개인적인 경험으로 플러그인이 특히 업데이트에 영향을 주는 것 같다.
  2. (필요하다면) FTP, DB 접속 비밀번호 변경하기
    업데이트 하는 과정에서 비밀번호를 바꾸고 싶을 수 있다. ‘서비스 접속관리’ 메뉴 > ‘FTP 비밀번호 변경’ 과 ‘DB 비밀번호 변경’ 메뉴를 활용해 변경하자. 특히, DB 비밀번호를 변경했다면 잊지말고 워드프레스에서도 변경하자.
  3. (사용하고 있다면) 워드프레스 앱 동작 확인하기
    업데이트 후 워드프레스 앱이 동작하지 않는 경우가 있다. 경험 상, 업그레이드 후 내 블로그와 젯팩 사이트 간 발생한 문제 때문인 경우가 많다. 젯팩 사이트에서도 Q&A를 통해 해결책을 제공해주지만, 번거롭거나 아무것도 통하지 않는다면 젯팩 플러그인 제거 후 다시 설치하자.

그 밖에

핵심만 설명하려고 했으나,  다쓰고나니 설명이 충분치 않은 것 같다. 카페24에서 관리하는 가이드나 Q&A 속 링크들이 정확하다. 이 글에서 모자란 부분은 그 정보를 활용해 업그레이드를 잘 마무리하길 바란다.

안드로이드에서 adb shell로 apk 추출하기

adb shell을 이용한 apk 추출 가이드는 그림과 함께 친절히 작성된 글이 인터넷에 이미 많이 있습니다. 개인적 기록 차원에서 적어둡니다.

설치된 패키지를 찾습니다.

>adb shell pm list packages | find "<패키지 이름이나 키워드>"

apk의 정확한 패키지 이름 확인 후, apk 설치 위치를 확인합니다.

>adb shell dumpsys package <패키지 이름> | find "path"

apk 설치 위치를 찾은 후 apk를 명령창이 실행되고 있는 현재 경로로 꺼냅니다.

>adb pull <apk 저장 경로>

 

그 밖에

  • P OS 단말에서 테스트 되었습니다.
  • 다운로드 받아 설치한 apk는 /data/app/* 아래 경로에 위치하지만, 권한이 없어 목록을 직접 확인할 수 없습니다.
  • 프리로드 앱 등은 다른 경로에 있을  수 있습니다.

 

Cleartext HTTP traffic to not permitted

P OS부터 targetSdk를 28로 올리면 네트워크 통신 시 아래와 같은 에러를 만날 수 있다.

08-21 18:15:53.165 16809-16917/me.sunphiz.android.test W/System.err: java.io.IOException: Cleartext HTTP traffic to <your-domain> not permitted
        at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
        ...

IOException가 발생한 원인은 P OS부터 앱이 서버와 통신 시 TLS 기반하도록 기본값이 변경되었기 때문이다. 이해를 돕기 위해 여기서는 가장 많이 쓰이는 HTTP에 대해서만 살펴보자면 https만을 쓰라는 뜻이다(물론, TLS 기반 통신을 하라는 말이 https를 쓰라는 뜻은 아니다).  안드로이드의 네트워크 통신 기본 설정이 바뀐 이유에 대해서는 이 글을, https와 SSL/TLS의 관계에 대해서는 이 글을 참고하자.

과거 https 통신 시 최초 핸드쉐이크(handshake) 절차가 비싸다(자원 소비가 크다)기 때문에 필요에 따라 http와 https를 적절히 사용하는 것을 옳다고 이야기 하기도 했다. 하지만, 최근 네트워크와 장비의 성능 향상과 더불어 개인 데이터 보호 측면에서 모든 통신을 https로 하는 것이 좋다는 의견이 많으며, 개인적으로도 옳다고 본다.

수정 방법은 크게 두 가지다. 하나는 시대에 흐름에 맞춰 모든 통신을 https 기반으로 고치는 것이다.  다른 하나는, http로 통신할 서버를 xml 파일에 열거하면 된다. 모든 통신을 갑자기 https로 바꾸는 것은 어려우니 여기서는 xml 파일을 통해 문제를 해결해보자.

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">insecure.example.com</domain>
        <domain includeSubdomains="true">insecure.cdn.example.com</domain>
    </domain-config>
</network-security-config>

안드로이드 가이드에서는 위처럼, http를 이용해 통신할 서버의 도메인을 모두 열거하고 나머지는 https를 사용하도록 권장한다. 만약 통신하는 서버의 dns를 모두 열거할 수 없거나, 모든 통신을 http로 하는 경우라면 아래처럼 기본값을 바꿀 수도 있다.

<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

위와 같이 하면 모든 clearText 통신이 허가되므로, 기본값이 바뀐 셈이다. 하지만 장기적으로는 모두 https 통신을 하는 것이 좋을 것이다.

참조

안드로이드 package dump 분석

이 글은 단말 dumpstate 파일 중에서 패키지 정보에 대한 부분만 소개하는 글이다. dumpstate의 설명을 찾는면, 이 글을 살펴보자.

패키지 dump는 dumpstate에도 포함되어 있고, 아래와 같은 명령어를 통해 단말에서 패키지 dump만 뽑을 수도 있다.

 adb shell dumpsys package <패키지 이름>

패키지 dump는 아래와 같은 모양을 갖고, 앱의 정보를 총망라하여 보여준다.

Package [com.android.calendar] (4a50e0):
    userId=10118
    pkg=Package{330fe6f com.android.calendar}
...

예를 들면,

  • 단말에서 처리가능한 MINE 타입, 스키마(Scheme) , 액션 정보
  • 등록한 권한(permission)
  • 버전 정보(versionName, versionCode)
  • 설치 위치(codePath, resourcePath)
  • 시그니처 정보(apkSigningVersion, signatures)

등 이다. 이 중에서 정보의 축약이 심해 이해가 잘 안되는 것들만 살펴보자.

플래그(flags)

패키지의 속성(property)을 표시하는 플래그다. 아래와 같이 속성을 가지고 있다면 표시되고, 속성이 없다면 표시되지 않는다.

Package [com.android.phone] (5328729):
	...
	flags=[ SYSTEM HAS_CODE PERSISTENT ALLOW_CLEAR_USER_DATA ]
	...
Package [com.google.android.apps.magazines] (6a6fc41):
	...
	flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP KILL_AFTER_RESTORE EXTERNAL_STORAGE ]
	...

위 예제의 전화 앱(com.android.phone)은 SYSTEM HAS_CODE PERSISTENT ALLOW_CLEAR_USER_DATA 속성을 갖고 있다.

패키지가 속성들의 가지고 있는지 판단하는 기준은 com.android.server.pm.Settings 소스 코드에서 살펴볼 수 있다.

...
static final Object[] FLAG_DUMP_SPEC = new Object[] {
ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
};
...

위 코드를 보면, ApplicationInfo.FLAG_SYSTEM가 true 이면 “SYSTEM” 속성을 가진 것으로 패키지 dump에 표시 되겠다. 그러므로, 저 코드를 참고하여 ApplicationInfo의 구글 API 가이드의 상수 설명을 보면 플래그의 의미를 알 수 있다. 그 중에 설명이 충분하지 않은 것들을 정리해보자.

  • “SYSTEM”
    프리로드 된 앱이 갖는 속성이다. 단말 제조사에서 바이너리 발행 시, /system/* 폴더에 앱을 탑재해야 한다. 그 예로, /system/priv-app/, /system/app/, /system/framework/ 이 있다.
    설치 위치가 /system/*이 아닌 /data/app/라도 시스템을 업데이트 한 경우라면 “SYSTEM” 속성을 가질 수 있다. 시스템을 업데이트한 경우에는 속성이 상속되기 때문이다.
    참고로, 이 속성은 패키지의 시그니처나 “PRIVILEGED”처럼 퍼미션 허가 여부에 영향을 미친다.
  • “UPDATED_SYSTEM_APP”
    시스템 앱을 업데이트한 앱이다. 설치 공간은 /data/app/*일 것이며, “SYSTEM” 속성도 함께 갖고 있다.
  • “PERSISTENT”
    항상 실행되는지 여부를 가리키는 플래그로 항상 동작해야하는 소수의 시스템 앱만 선언한다.
    AndroidManifest.xml 파일 내 <application/>의 파라미터로 명시적 선언해야한다.
    예) 전화, NFC 앱
  • “EXTERNAL_STORAGE”
    외부 저장공간에 저장된 경우에 표시되는 속성이다.
    앱의 제작자가 AndroidManifest.xml 파일 내 <manifest/>의 android:installLocation 파라미터로 명시적 선언되어야 이동이 가능하다.
    만약 이동 가능한 앱이라면, “Settings – Apps – <어플리케이션 이름> 선택 – Storage 선택 – 저장공간 이동”, SD카드가 있어야 메뉴가 노출된다.
    예) 구글 뉴스 앱
  • “LARGE_HEAP”
    앱 실행 시 시스템으로 부터 더 큰 Heap 메모리를 할당받는다.
    AndroidManifest.xml 파일 내 <application/>의 파라미터로 명시적 선언해야 한다.
    시스템에 따라, 앱에 할당하는 기본 Heap 메모리 크기가 다르므로, LARGE_HEAP 속성을 선언했을 때 추가할당하는 heap 크기도 단말마다 다를 수 있다.

프라이빗 플래그(privateFlags)

privateFlags라는 속성 중에서, 한 가지만 살펴보자.

Package [com.android.phone] (5328729):
    ...
    privateFlags=[ PRIVILEGED DEFAULT_TO_DEVICE_PROTECTED_STORAGE DIRECT_BOOT_AWARE PARTIALLY_DIRECT_BOOT_AWARE PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION ]
    ...
  • “PRIVILEGED”
    앱 중에서 /system/* 이하에 설치된 경우 “SYSTEM” 속성을 갖고 있다고 했다. 시스템 앱 중에서도 설치된 상세 위치가 /system/priv-app/*인 경우 추가적으로 privateFlags에 이 속성을 갖는다.
    참고로, 이 속성은 “SYSTEM” 플래그나 패키지 시그니처러럼 퍼미션 허가 여부에 영향을 미칠 수 있다.

패키지 시그니처(signatures)

패키지의 시그니처 정보를 확인할 수 있다.

Package [com.android.phone] (5328729):
	...
	signatures=PackageSignatures{15f0d38 [b378e95c]}
	...
Package [com.google.android.apps.magazines] (6a6fc41):
	...
    signatures=PackageSignatures{6261b7d [e3ca78d8]}
	...    

위 예시 속 패키지는 com.android.phone은 기본 전화 앱, com.google.android.apps.magazines는 구글 뉴스 앱이다.  signatures 파라미터의 대괄호 안에 signature가 있고, 이 값이 같은 앱들은 같은 keystore를 통해 signing이 된 것이다.

참고로, 시그니처도 “SYSTEM”이나 “PRIVILEGED” 속성과 갖이 퍼미션 허가 여부에 영향을 미친다.

패키지 상태(활성화, 강제 종료 등)

패키지 활성화(enable) 여부나 강제 종료 여부도 확인할 수 있다.

...
User 0:  installed=true hidden=false stopped=false notLaunched=false enabled=0
...

위 패키지 정보 로그 중, stopped 파라미터는 설정 > 어플리케이션 관리자 > 앱 > 강제 종료 되었는지 여부를 가리킨다.

또 enabled 파라미터는 패키지 활성화 여부를 보여준다. 0(Default), 1(Enabled), 2(Diabled), 3(Disabled by user), 4(Diabled until used) 등으로 여기에 사용되는 값은 안드로이드 버전에 따라 추가되기도 하니, PackageManager의 상수들을 참조하면 된다.

그 밖에

  • 프리로드 앱(단말에 처음부터 포함된 앱)이 업데이트 된 경우, 프리로드 앱 정보와 업데이트 된 앱 의 패키지 정보가 모두 보인다.
  • 플래그 중에는 ApplicationInfo.FLAG_IS_GAME 처럼, deprecated된 것도 있다.
  • 퍼미션 허가 여부에 대한 자세한 내용은 이 글을 살펴보자.

참고

상황 별 호출되는 액티비티의 생명주기 메소드들

안드로이드의 앱을 구성하는 일명 4대 컴포넌트는 모두 생명주기가 있다. 이 중, 가장 복잡한 생명주기를 가진 컴포넌트가 액티비티다. 액티비티의 생명주기에 대한 글은 수없이 많다. 하지만, 그런 글들을 읽고 액티비티의 생명주기를 이해하더라도, 문제 분석 시 ‘그래서 지금 사용자가 뭘 했길래 이렇게 호출된거야?’라는 생각이 드는 경우가 있다. 그러므로, 여기서는 액티비티 생명주기 소개 대신에 상황 별로 호출되는 액티비티의 생명주기 메소드들을 정리한다.

https://developer.android.com/reference/android/app/Activity

참고로, 여기서 상황이란 ‘앱 아이콘을 통해 액티비티를 최초 실행 시’ 등 액티비티에게 변화를 주는 액션을 사용자가 하는 때이며, O OS 단말 기준으로 테스트했다.

onCreate() > onStart() > onResume() 순으로 호출되는 경우

  • (액티비티 미실행 상태) – 앱아이콘 클릭 – 액티비티 최초 실행
  • (최근 앱 목록 표시 중, 액티비티는 미실행 상태) – 액티비티 선택 – 액티비티 실행

onCreate() > onStart() > onResume() > onPause() > onStop() 순으로 호출되는 경우

  • (화면 잠김 상태) – ADB 커맨드를 통한 액티비티 실행

onRestart() > onStart() > onResume() 순으로 호출되는 경우

  • (액티비티 foreground 상태에서 화면 잠김 상태) – 화면 잠금 해제(홈이나 전원 버튼, 필요하다면 비밀번호 입력 등) – 액티비티 실행
  • (액티비티를 실행한 적이 있으며 숨겨져 있는 상태) – 액티비티 실행(앱 아이콘 클릭 등) – 액티비티 실행

onPause()만 호출되는 경우

  • (액티비티 foreground 상태) – 다른 액티비티 실행

onPause() > onStop() 순으로 호출되는 경우

  • (액티비티 foreground 상태) – 전원 버튼 누르기 – 화면 잠금
  • (액티비티 foreground 상태) – 홈 버튼 누르기 – 런쳐 홈으로 이동

onPause() > onStop() > onDestroy() 순으로 호출되는 경우

  • (액티비티 foreground 상태) – 뒤로가기 버튼 눌러 액티비티 나가기

onDestroy()만 호출되는 경우

  • (최근 앱 목록 표시 중) – 액티비티 제거하기(밀어내기나 ‘X’ 버튼)

그 밖에

  • 액티비티를 실행한 적이 있다는 말의 의미는, 액티비티 컴포넌트가 소멸되지 않고 메모리에 상주하고 있어 재사용될 수 있다는 의미다.
  • 최근 목록 앱에 액티비티가 표시되더라도 액티비티는 미실행 상태일 수 있다. 최근 목록 앱은 파일 형태로 저장되어 단말 재부팅 후에도 히스토리 관리를 위해 유지되기 때문이다.
  • 액티비티 위에 다이얼로그를 표시하는 경우는, 생명주기 변화가 없다. 액티비티 위에 액티비티가 뜨는 경우에만, 변화가 있다.
  • 액티비티 컴포넌트의 onDestroy() 메소드가 호출되지 않고도, 자원 부족으로 인해 컴포넌트가 사라지기도 한다.

참고